vellum-ai 0.13.18__py3-none-any.whl → 0.13.20__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/core/client_wrapper.py +1 -1
- vellum/client/resources/test_suites/client.py +44 -8
- vellum/client/types/__init__.py +2 -0
- vellum/client/types/container_image_container_image_tag.py +21 -0
- vellum/client/types/container_image_read.py +2 -1
- vellum/types/container_image_container_image_tag.py +3 -0
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py +48 -3
- vellum/workflows/nodes/core/retry_node/node.py +13 -7
- vellum/workflows/outputs/base.py +11 -0
- {vellum_ai-0.13.18.dist-info → vellum_ai-0.13.20.dist-info}/METADATA +1 -1
- {vellum_ai-0.13.18.dist-info → vellum_ai-0.13.20.dist-info}/RECORD +39 -37
- vellum_cli/config.py +69 -11
- vellum_cli/tests/test_pull.py +42 -1
- vellum_ee/workflows/display/nodes/vellum/__init__.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py +2 -3
- vellum_ee/workflows/display/nodes/vellum/utils.py +1 -1
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +5 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +9 -30
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +22 -36
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +35 -70
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_error_node_serialization.py +2 -2
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_generic_node_serialization.py +2 -2
- 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 +24 -57
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +4 -4
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +2 -2
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_prompt_deployment_serialization.py +2 -2
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_search_node_serialization.py +2 -2
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_deployment_serialization.py +4 -4
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py +2 -2
- vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py +2 -2
- vellum_ee/workflows/display/utils/vellum.py +0 -2
- vellum_ee/workflows/display/vellum.py +0 -2
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py +1 -8
- vellum_ee/workflows/tests/local_workflow/display/workflow.py +0 -2
- {vellum_ai-0.13.18.dist-info → vellum_ai-0.13.20.dist-info}/LICENSE +0 -0
- {vellum_ai-0.13.18.dist-info → vellum_ai-0.13.20.dist-info}/WHEEL +0 -0
- {vellum_ai-0.13.18.dist-info → vellum_ai-0.13.20.dist-info}/entry_points.txt +0 -0
vellum_cli/config.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from collections import defaultdict
|
1
2
|
from dataclasses import field
|
2
3
|
import json
|
3
4
|
import os
|
@@ -88,6 +89,50 @@ class WorkflowConfig(UniversalBaseModel):
|
|
88
89
|
)
|
89
90
|
|
90
91
|
|
92
|
+
def merge_workflows_by_sandbox_id(
|
93
|
+
workflows: List[WorkflowConfig], other_workflows: List[WorkflowConfig]
|
94
|
+
) -> List[WorkflowConfig]:
|
95
|
+
merged_workflows: List[WorkflowConfig] = []
|
96
|
+
for self_workflow in workflows:
|
97
|
+
if self_workflow.workflow_sandbox_id is None:
|
98
|
+
# If the user defines a workflow in the pyproject.toml without a sandbox_id,
|
99
|
+
# we merge the workflow with one of the ones in the lockfile.
|
100
|
+
other_workflow = next(
|
101
|
+
(
|
102
|
+
other_workflow
|
103
|
+
for other_workflow in other_workflows
|
104
|
+
if self_workflow.workspace == other_workflow.workspace
|
105
|
+
),
|
106
|
+
None,
|
107
|
+
)
|
108
|
+
if other_workflow is not None:
|
109
|
+
merged_workflows.append(self_workflow.merge(other_workflow))
|
110
|
+
else:
|
111
|
+
merged_workflows.append(self_workflow)
|
112
|
+
else:
|
113
|
+
# If the user defines a workflow in the pyproject.toml with a sandbox_id,
|
114
|
+
# we merge the workflow with one of the ones in the lockfile with the same sandbox_id.
|
115
|
+
other_workflow = next(
|
116
|
+
(
|
117
|
+
other_workflow
|
118
|
+
for other_workflow in other_workflows
|
119
|
+
if self_workflow.workflow_sandbox_id == other_workflow.workflow_sandbox_id
|
120
|
+
),
|
121
|
+
None,
|
122
|
+
)
|
123
|
+
if other_workflow is not None:
|
124
|
+
merged_workflows.append(self_workflow.merge(other_workflow))
|
125
|
+
else:
|
126
|
+
merged_workflows.append(self_workflow)
|
127
|
+
|
128
|
+
workflow_sandbox_ids_so_far = {workflow.workflow_sandbox_id for workflow in merged_workflows}
|
129
|
+
for other_workflow in other_workflows:
|
130
|
+
if other_workflow.workflow_sandbox_id not in workflow_sandbox_ids_so_far:
|
131
|
+
merged_workflows.append(other_workflow)
|
132
|
+
|
133
|
+
return merged_workflows
|
134
|
+
|
135
|
+
|
91
136
|
class VellumCliConfig(UniversalBaseModel):
|
92
137
|
version: Literal["1.0"] = "1.0"
|
93
138
|
workflows: List[WorkflowConfig] = field(default_factory=list)
|
@@ -97,24 +142,31 @@ class VellumCliConfig(UniversalBaseModel):
|
|
97
142
|
lockfile_path = os.path.join(os.getcwd(), LOCKFILE_PATH)
|
98
143
|
with open(lockfile_path, "w") as f:
|
99
144
|
json.dump(self.model_dump(), f, indent=2, cls=DefaultStateEncoder)
|
145
|
+
# Makes sure the file ends with a newline, consistent with most autoformatters
|
146
|
+
f.write("\n")
|
100
147
|
|
101
148
|
def merge(self, other: "VellumCliConfig") -> "VellumCliConfig":
|
102
149
|
if other.version != self.version:
|
103
150
|
raise ValueError("Lockfile version mismatch")
|
104
151
|
|
105
|
-
|
106
|
-
|
107
|
-
all_modules = sorted(set(
|
152
|
+
self_workflows_by_module = self.get_workflows_by_module_mapping()
|
153
|
+
other_workflows_by_module = other.get_workflows_by_module_mapping()
|
154
|
+
all_modules = sorted(set(self_workflows_by_module.keys()).union(set(other_workflows_by_module.keys())))
|
108
155
|
merged_workflows = []
|
109
156
|
for module in all_modules:
|
110
|
-
|
111
|
-
|
112
|
-
if
|
113
|
-
merged_workflows.
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
157
|
+
self_workflows = self_workflows_by_module.get(module)
|
158
|
+
other_workflows = other_workflows_by_module.get(module)
|
159
|
+
if self_workflows and other_workflows:
|
160
|
+
merged_workflows.extend(
|
161
|
+
merge_workflows_by_sandbox_id(
|
162
|
+
self_workflows,
|
163
|
+
other_workflows,
|
164
|
+
)
|
165
|
+
)
|
166
|
+
elif self_workflows:
|
167
|
+
merged_workflows.extend(self_workflows)
|
168
|
+
elif other_workflows:
|
169
|
+
merged_workflows.extend(other_workflows)
|
118
170
|
|
119
171
|
self_workspace_by_name = {workspace.name: workspace for workspace in self.workspaces}
|
120
172
|
other_workspace_by_name = {workspace.name: workspace for workspace in other.workspaces}
|
@@ -132,6 +184,12 @@ class VellumCliConfig(UniversalBaseModel):
|
|
132
184
|
|
133
185
|
return VellumCliConfig(workflows=merged_workflows, workspaces=merged_workspaces, version=self.version)
|
134
186
|
|
187
|
+
def get_workflows_by_module_mapping(self) -> Dict[str, List[WorkflowConfig]]:
|
188
|
+
workflows_by_module = defaultdict(list)
|
189
|
+
for workflow in self.workflows:
|
190
|
+
workflows_by_module[workflow.module].append(workflow)
|
191
|
+
return workflows_by_module
|
192
|
+
|
135
193
|
|
136
194
|
def load_vellum_cli_config(root_dir: Optional[str] = None) -> VellumCliConfig:
|
137
195
|
if root_dir is None:
|
vellum_cli/tests/test_pull.py
CHANGED
@@ -428,7 +428,7 @@ def test_pull__sandbox_id_with_other_workflow_deployment_in_lock(vellum_client,
|
|
428
428
|
"workflows": [
|
429
429
|
{
|
430
430
|
"module": module,
|
431
|
-
"workflow_sandbox_id":
|
431
|
+
"workflow_sandbox_id": workflow_sandbox_id,
|
432
432
|
"ignore": "tests/*",
|
433
433
|
"deployments": [
|
434
434
|
{
|
@@ -646,3 +646,44 @@ def test_pull__module_not_in_config(vellum_client, mock_module):
|
|
646
646
|
"workspace": "default",
|
647
647
|
}
|
648
648
|
]
|
649
|
+
|
650
|
+
|
651
|
+
def test_pull__multiple_instances_of_same_module__keep_when_pulling_another_module(vellum_client, mock_module):
|
652
|
+
# GIVEN a module on the user's filesystem
|
653
|
+
module = mock_module.module
|
654
|
+
temp_dir = mock_module.temp_dir
|
655
|
+
workflow_sandbox_id = mock_module.workflow_sandbox_id
|
656
|
+
|
657
|
+
# AND the vellum lock file has two instances of some other module
|
658
|
+
lock_data = {
|
659
|
+
"workflows": [
|
660
|
+
{
|
661
|
+
"module": "some_other_module",
|
662
|
+
"workflow_sandbox_id": str(uuid4()),
|
663
|
+
"workspace": "default",
|
664
|
+
},
|
665
|
+
{
|
666
|
+
"module": "some_other_module",
|
667
|
+
"workflow_sandbox_id": str(uuid4()),
|
668
|
+
"workspace": "other",
|
669
|
+
},
|
670
|
+
]
|
671
|
+
}
|
672
|
+
lock_json = os.path.join(temp_dir, "vellum.lock.json")
|
673
|
+
with open(lock_json, "w") as f:
|
674
|
+
json.dump(lock_data, f)
|
675
|
+
|
676
|
+
# AND the workflow pull API call returns a zip file
|
677
|
+
vellum_client.workflows.pull.return_value = iter([_zip_file_map({"workflow.py": "print('hello')"})])
|
678
|
+
|
679
|
+
# WHEN the user runs the pull command on the new module
|
680
|
+
runner = CliRunner()
|
681
|
+
result = runner.invoke(cli_main, ["workflows", "pull", module, "--workflow-sandbox-id", workflow_sandbox_id])
|
682
|
+
|
683
|
+
# THEN the command returns successfully
|
684
|
+
assert result.exit_code == 0, (result.output, result.exception)
|
685
|
+
|
686
|
+
# AND the lockfile should have all three entries
|
687
|
+
with open(lock_json) as f:
|
688
|
+
lock_data = json.load(f)
|
689
|
+
assert len(lock_data["workflows"]) == 3
|
@@ -18,7 +18,6 @@ from .try_node import BaseTryNodeDisplay
|
|
18
18
|
|
19
19
|
# All node display classes must be imported here to be registered in BaseNodeDisplay's node display registry
|
20
20
|
__all__ = [
|
21
|
-
"BaseRetryNodeDisplay",
|
22
21
|
"BaseAPINodeDisplay",
|
23
22
|
"BaseCodeExecutionNodeDisplay",
|
24
23
|
"BaseConditionalNodeDisplay",
|
@@ -31,6 +30,7 @@ __all__ = [
|
|
31
30
|
"BaseMergeNodeDisplay",
|
32
31
|
"BaseNoteNodeDisplay",
|
33
32
|
"BasePromptDeploymentNodeDisplay",
|
33
|
+
"BaseRetryNodeDisplay",
|
34
34
|
"BaseSearchNodeDisplay",
|
35
35
|
"BaseSubworkflowDeploymentNodeDisplay",
|
36
36
|
"BaseTemplatingNodeDisplay",
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from uuid import UUID
|
2
|
-
from typing import
|
2
|
+
from typing import Generic, Optional, TypeVar
|
3
3
|
|
4
4
|
from vellum.workflows.nodes import SubworkflowDeploymentNode
|
5
5
|
from vellum.workflows.types.core import JsonObject
|
@@ -15,7 +15,6 @@ _SubworkflowDeploymentNodeType = TypeVar("_SubworkflowDeploymentNodeType", bound
|
|
15
15
|
class BaseSubworkflowDeploymentNodeDisplay(
|
16
16
|
BaseNodeVellumDisplay[_SubworkflowDeploymentNodeType], Generic[_SubworkflowDeploymentNodeType]
|
17
17
|
):
|
18
|
-
subworkflow_input_ids_by_name: ClassVar[Dict[str, UUID]] = {}
|
19
18
|
|
20
19
|
def serialize(
|
21
20
|
self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **kwargs
|
@@ -30,7 +29,7 @@ class BaseSubworkflowDeploymentNodeDisplay(
|
|
30
29
|
input_name=variable_name,
|
31
30
|
value=variable_value,
|
32
31
|
display_context=display_context,
|
33
|
-
input_id=self.
|
32
|
+
input_id=self.node_input_ids_by_name.get(variable_name),
|
34
33
|
)
|
35
34
|
for variable_name, variable_value in subworkflow_inputs.items()
|
36
35
|
]
|
@@ -27,7 +27,7 @@ def create_node_input(
|
|
27
27
|
input_name: str,
|
28
28
|
value: Any,
|
29
29
|
display_context: WorkflowDisplayContext,
|
30
|
-
input_id: Union[Optional[UUID], Optional[str]],
|
30
|
+
input_id: Union[Optional[UUID], Optional[str]] = None,
|
31
31
|
pointer_type: Optional[Type[NodeInputValuePointerRule]] = ConstantValuePointer,
|
32
32
|
) -> NodeInput:
|
33
33
|
input_id = str(input_id) if input_id else str(uuid4_from_hash(f"{node_id}|{input_name}"))
|
@@ -80,6 +80,11 @@ def test_serialize_node__retry(serialize_node):
|
|
80
80
|
"module": ["vellum", "workflows", "nodes", "core", "retry_node", "node"],
|
81
81
|
},
|
82
82
|
"attributes": [
|
83
|
+
{
|
84
|
+
"id": "8a07dc58-3fed-41d4-8ca6-31ee0bb86c61",
|
85
|
+
"name": "delay",
|
86
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "JSON", "value": None}},
|
87
|
+
},
|
83
88
|
{
|
84
89
|
"id": "f388e93b-8c68-4f54-8577-bbd0c9091557",
|
85
90
|
"name": "max_attempts",
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py
CHANGED
@@ -210,11 +210,11 @@ def test_serialize_workflow(vellum_client):
|
|
210
210
|
"target_handle_id": "06853542-e1a1-4a00-bd1e-4ac40f347b32",
|
211
211
|
"output_id": "9a37bf7d-484e-4725-903e-f3254df38a0a",
|
212
212
|
"output_type": "JSON",
|
213
|
-
"node_input_id": "
|
213
|
+
"node_input_id": "b49f0f85-37fc-4686-81a7-287c06634661",
|
214
214
|
},
|
215
215
|
"inputs": [
|
216
216
|
{
|
217
|
-
"id": "
|
217
|
+
"id": "b49f0f85-37fc-4686-81a7-287c06634661",
|
218
218
|
"key": "node_input",
|
219
219
|
"value": {
|
220
220
|
"rules": [
|
@@ -233,14 +233,7 @@ def test_serialize_workflow(vellum_client):
|
|
233
233
|
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
234
234
|
"base": {
|
235
235
|
"name": "FinalOutputNode",
|
236
|
-
"module": [
|
237
|
-
"vellum",
|
238
|
-
"workflows",
|
239
|
-
"nodes",
|
240
|
-
"displayable",
|
241
|
-
"final_output_node",
|
242
|
-
"node",
|
243
|
-
],
|
236
|
+
"module": ["vellum", "workflows", "nodes", "displayable", "final_output_node", "node"],
|
244
237
|
},
|
245
238
|
"definition": None,
|
246
239
|
},
|
@@ -253,11 +246,11 @@ def test_serialize_workflow(vellum_client):
|
|
253
246
|
"target_handle_id": "80d0894f-642e-4d2e-b43a-f236e7bedb3c",
|
254
247
|
"output_id": "5090e96d-5787-4a08-bf58-129101cf2548",
|
255
248
|
"output_type": "JSON",
|
256
|
-
"node_input_id": "
|
249
|
+
"node_input_id": "5e892e5b-0004-4a04-bd2e-1ea9e0e5d3f9",
|
257
250
|
},
|
258
251
|
"inputs": [
|
259
252
|
{
|
260
|
-
"id": "
|
253
|
+
"id": "5e892e5b-0004-4a04-bd2e-1ea9e0e5d3f9",
|
261
254
|
"key": "node_input",
|
262
255
|
"value": {
|
263
256
|
"rules": [
|
@@ -276,14 +269,7 @@ def test_serialize_workflow(vellum_client):
|
|
276
269
|
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
277
270
|
"base": {
|
278
271
|
"name": "FinalOutputNode",
|
279
|
-
"module": [
|
280
|
-
"vellum",
|
281
|
-
"workflows",
|
282
|
-
"nodes",
|
283
|
-
"displayable",
|
284
|
-
"final_output_node",
|
285
|
-
"node",
|
286
|
-
],
|
272
|
+
"module": ["vellum", "workflows", "nodes", "displayable", "final_output_node", "node"],
|
287
273
|
},
|
288
274
|
"definition": None,
|
289
275
|
},
|
@@ -296,11 +282,11 @@ def test_serialize_workflow(vellum_client):
|
|
296
282
|
"target_handle_id": "0c98c306-b519-40d7-8b05-321b1dfd7f11",
|
297
283
|
"output_id": "44ea8d75-e2a8-4627-85b1-8504b65d25c9",
|
298
284
|
"output_type": "NUMBER",
|
299
|
-
"node_input_id": "
|
285
|
+
"node_input_id": "14345321-7e6b-4e2a-918a-7a5b0064f047",
|
300
286
|
},
|
301
287
|
"inputs": [
|
302
288
|
{
|
303
|
-
"id": "
|
289
|
+
"id": "14345321-7e6b-4e2a-918a-7a5b0064f047",
|
304
290
|
"key": "node_input",
|
305
291
|
"value": {
|
306
292
|
"rules": [
|
@@ -319,14 +305,7 @@ def test_serialize_workflow(vellum_client):
|
|
319
305
|
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
320
306
|
"base": {
|
321
307
|
"name": "FinalOutputNode",
|
322
|
-
"module": [
|
323
|
-
"vellum",
|
324
|
-
"workflows",
|
325
|
-
"nodes",
|
326
|
-
"displayable",
|
327
|
-
"final_output_node",
|
328
|
-
"node",
|
329
|
-
],
|
308
|
+
"module": ["vellum", "workflows", "nodes", "displayable", "final_output_node", "node"],
|
330
309
|
},
|
331
310
|
"definition": None,
|
332
311
|
},
|
@@ -125,11 +125,11 @@ def test_serialize_workflow_with_filepath():
|
|
125
125
|
"target_handle_id": "30fb0f4a-61c3-49de-a0aa-7dfdcee6ea07",
|
126
126
|
"output_id": "f6a3e3e0-f83f-4491-8b7a-b20fddd7160c",
|
127
127
|
"output_type": "NUMBER",
|
128
|
-
"node_input_id": "
|
128
|
+
"node_input_id": "529bdd20-0985-4c99-87dc-590907937c1d",
|
129
129
|
},
|
130
130
|
"inputs": [
|
131
131
|
{
|
132
|
-
"id": "
|
132
|
+
"id": "529bdd20-0985-4c99-87dc-590907937c1d",
|
133
133
|
"key": "node_input",
|
134
134
|
"value": {
|
135
135
|
"rules": [
|
@@ -161,11 +161,11 @@ def test_serialize_workflow_with_filepath():
|
|
161
161
|
"target_handle_id": "1e126004-9de7-42c0-b1e1-87f9eb0642e2",
|
162
162
|
"output_id": "1cee930f-342f-421c-89fc-ff212b3764bb",
|
163
163
|
"output_type": "STRING",
|
164
|
-
"node_input_id": "
|
164
|
+
"node_input_id": "09501b65-d9b3-4920-81d4-96f93c840667",
|
165
165
|
},
|
166
166
|
"inputs": [
|
167
167
|
{
|
168
|
-
"id": "
|
168
|
+
"id": "09501b65-d9b3-4920-81d4-96f93c840667",
|
169
169
|
"key": "node_input",
|
170
170
|
"value": {
|
171
171
|
"rules": [
|
@@ -358,11 +358,11 @@ def test_serialize_workflow_with_code():
|
|
358
358
|
"target_handle_id": "de8f2cc2-8c32-4782-87d5-4eb5afcd42e3",
|
359
359
|
"output_id": "283d6849-f3ed-4beb-b261-cf70f90e8d10",
|
360
360
|
"output_type": "NUMBER",
|
361
|
-
"node_input_id": "
|
361
|
+
"node_input_id": "101d5222-8578-413a-be80-b1acf7559a0d",
|
362
362
|
},
|
363
363
|
"inputs": [
|
364
364
|
{
|
365
|
-
"id": "
|
365
|
+
"id": "101d5222-8578-413a-be80-b1acf7559a0d",
|
366
366
|
"key": "node_input",
|
367
367
|
"value": {
|
368
368
|
"rules": [
|
@@ -394,11 +394,11 @@ def test_serialize_workflow_with_code():
|
|
394
394
|
"target_handle_id": "6b7d7f2c-5cc8-4005-9e66-cdb2c97b1998",
|
395
395
|
"output_id": "4c136180-050b-4422-a7a4-2a1c6729042c",
|
396
396
|
"output_type": "STRING",
|
397
|
-
"node_input_id": "
|
397
|
+
"node_input_id": "de7ea5c4-da2f-4cfd-9192-0257d0f9ba53",
|
398
398
|
},
|
399
399
|
"inputs": [
|
400
400
|
{
|
401
|
-
"id": "
|
401
|
+
"id": "de7ea5c4-da2f-4cfd-9192-0257d0f9ba53",
|
402
402
|
"key": "node_input",
|
403
403
|
"value": {
|
404
404
|
"rules": [
|
@@ -601,29 +601,17 @@ def test_serialize_workflow__try_wrapped():
|
|
601
601
|
{
|
602
602
|
"id": "af4fc1ef-7701-43df-b5e7-4f354f707db2",
|
603
603
|
"type": "TERMINAL",
|
604
|
-
"base": {
|
605
|
-
"module": [
|
606
|
-
"vellum",
|
607
|
-
"workflows",
|
608
|
-
"nodes",
|
609
|
-
"displayable",
|
610
|
-
"final_output_node",
|
611
|
-
"node",
|
612
|
-
],
|
613
|
-
"name": "FinalOutputNode",
|
614
|
-
},
|
615
|
-
"definition": None,
|
616
604
|
"data": {
|
617
605
|
"label": "Final Output",
|
618
606
|
"name": "log",
|
619
607
|
"target_handle_id": "d243df8d-46f6-4928-ac31-7c775c5d73a9",
|
620
608
|
"output_id": "5fbd27a0-9831-49c7-93c8-9c2a28c78696",
|
621
609
|
"output_type": "STRING",
|
622
|
-
"node_input_id": "
|
610
|
+
"node_input_id": "a6ffaacf-1284-4e70-907e-042bb281e6fa",
|
623
611
|
},
|
624
612
|
"inputs": [
|
625
613
|
{
|
626
|
-
"id": "
|
614
|
+
"id": "a6ffaacf-1284-4e70-907e-042bb281e6fa",
|
627
615
|
"key": "node_input",
|
628
616
|
"value": {
|
629
617
|
"rules": [
|
@@ -640,33 +628,26 @@ def test_serialize_workflow__try_wrapped():
|
|
640
628
|
}
|
641
629
|
],
|
642
630
|
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
643
|
-
},
|
644
|
-
{
|
645
|
-
"id": "4cbfa5f7-fc12-4ab2-81cb-168c5caef4f0",
|
646
|
-
"type": "TERMINAL",
|
647
631
|
"base": {
|
648
|
-
"module": [
|
649
|
-
"vellum",
|
650
|
-
"workflows",
|
651
|
-
"nodes",
|
652
|
-
"displayable",
|
653
|
-
"final_output_node",
|
654
|
-
"node",
|
655
|
-
],
|
656
632
|
"name": "FinalOutputNode",
|
633
|
+
"module": ["vellum", "workflows", "nodes", "displayable", "final_output_node", "node"],
|
657
634
|
},
|
658
635
|
"definition": None,
|
636
|
+
},
|
637
|
+
{
|
638
|
+
"id": "4cbfa5f7-fc12-4ab2-81cb-168c5caef4f0",
|
639
|
+
"type": "TERMINAL",
|
659
640
|
"data": {
|
660
641
|
"label": "Final Output",
|
661
642
|
"name": "result",
|
662
643
|
"target_handle_id": "9c43709e-25cb-4548-b840-3fcf6a1c9f3e",
|
663
644
|
"output_id": "400f9ffe-e700-4204-a810-e06123565947",
|
664
645
|
"output_type": "NUMBER",
|
665
|
-
"node_input_id": "
|
646
|
+
"node_input_id": "2cbb7351-a3e8-4a6b-b33e-204b04da7ad6",
|
666
647
|
},
|
667
648
|
"inputs": [
|
668
649
|
{
|
669
|
-
"id": "
|
650
|
+
"id": "2cbb7351-a3e8-4a6b-b33e-204b04da7ad6",
|
670
651
|
"key": "node_input",
|
671
652
|
"value": {
|
672
653
|
"rules": [
|
@@ -683,6 +664,11 @@ def test_serialize_workflow__try_wrapped():
|
|
683
664
|
}
|
684
665
|
],
|
685
666
|
"display_data": {"position": {"x": 0.0, "y": 0.0}},
|
667
|
+
"base": {
|
668
|
+
"name": "FinalOutputNode",
|
669
|
+
"module": ["vellum", "workflows", "nodes", "displayable", "final_output_node", "node"],
|
670
|
+
},
|
671
|
+
"definition": None,
|
686
672
|
},
|
687
673
|
],
|
688
674
|
sorted(final_output_nodes, key=lambda x: x["id"], reverse=True),
|