vellum-ai 1.7.5__py3-none-any.whl → 1.7.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vellum/client/core/client_wrapper.py +2 -2
- vellum/workflows/nodes/bases/base.py +28 -9
- vellum/workflows/nodes/bases/base_adornment_node.py +53 -1
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +3 -1
- vellum/workflows/nodes/displayable/search_node/node.py +2 -1
- vellum/workflows/nodes/displayable/search_node/tests/test_node.py +14 -0
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +7 -1
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py +1 -1
- vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py +54 -0
- vellum/workflows/nodes/displayable/tool_calling_node/utils.py +26 -24
- vellum/workflows/runner/runner.py +42 -52
- vellum/workflows/triggers/__init__.py +2 -1
- vellum/workflows/triggers/integration.py +62 -0
- vellum/workflows/triggers/tests/__init__.py +1 -0
- vellum/workflows/triggers/tests/test_integration.py +102 -0
- vellum/workflows/workflows/base.py +17 -3
- {vellum_ai-1.7.5.dist-info → vellum_ai-1.7.7.dist-info}/METADATA +1 -1
- {vellum_ai-1.7.5.dist-info → vellum_ai-1.7.7.dist-info}/RECORD +29 -26
- vellum_cli/push.py +1 -5
- vellum_cli/tests/test_push.py +86 -0
- vellum_ee/workflows/display/nodes/base_node_display.py +1 -1
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +16 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_manual_trigger_serialization.py +16 -19
- vellum_ee/workflows/display/utils/expressions.py +11 -11
- vellum_ee/workflows/display/workflows/base_workflow_display.py +23 -14
- vellum_ee/workflows/tests/test_server.py +40 -1
- {vellum_ai-1.7.5.dist-info → vellum_ai-1.7.7.dist-info}/LICENSE +0 -0
- {vellum_ai-1.7.5.dist-info → vellum_ai-1.7.7.dist-info}/WHEEL +0 -0
- {vellum_ai-1.7.5.dist-info → vellum_ai-1.7.7.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,102 @@
|
|
1
|
+
"""Tests for IntegrationTrigger base class."""
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from vellum.workflows.nodes.bases.base import BaseNode
|
6
|
+
from vellum.workflows.triggers.integration import IntegrationTrigger
|
7
|
+
|
8
|
+
|
9
|
+
def test_integration_trigger__is_abstract():
|
10
|
+
"""IntegrationTrigger cannot be instantiated directly (ABC)."""
|
11
|
+
# WHEN we try to call process_event on IntegrationTrigger directly
|
12
|
+
# THEN it raises NotImplementedError
|
13
|
+
with pytest.raises(NotImplementedError, match="must implement process_event"):
|
14
|
+
IntegrationTrigger.process_event({})
|
15
|
+
|
16
|
+
|
17
|
+
def test_integration_trigger__outputs_class_exists():
|
18
|
+
"""IntegrationTrigger has Outputs class."""
|
19
|
+
# GIVEN IntegrationTrigger
|
20
|
+
# THEN it has an Outputs class
|
21
|
+
assert hasattr(IntegrationTrigger, "Outputs")
|
22
|
+
|
23
|
+
|
24
|
+
def test_integration_trigger__can_be_subclassed():
|
25
|
+
"""IntegrationTrigger can be subclassed to create concrete triggers."""
|
26
|
+
|
27
|
+
# GIVEN a concrete implementation of IntegrationTrigger
|
28
|
+
class TestTrigger(IntegrationTrigger):
|
29
|
+
class Outputs(IntegrationTrigger.Outputs):
|
30
|
+
data: str
|
31
|
+
|
32
|
+
@classmethod
|
33
|
+
def process_event(cls, event_data: dict):
|
34
|
+
return cls.Outputs(data=event_data.get("data", ""))
|
35
|
+
|
36
|
+
# WHEN we process an event
|
37
|
+
result = TestTrigger.process_event({"data": "test"})
|
38
|
+
|
39
|
+
# THEN it returns the expected outputs
|
40
|
+
assert result.data == "test"
|
41
|
+
|
42
|
+
|
43
|
+
def test_integration_trigger__graph_syntax():
|
44
|
+
"""IntegrationTrigger can be used in graph syntax."""
|
45
|
+
|
46
|
+
# GIVEN a concrete trigger and a node
|
47
|
+
class TestTrigger(IntegrationTrigger):
|
48
|
+
class Outputs(IntegrationTrigger.Outputs):
|
49
|
+
value: str
|
50
|
+
|
51
|
+
@classmethod
|
52
|
+
def process_event(cls, event_data: dict):
|
53
|
+
return cls.Outputs(value=event_data.get("value", ""))
|
54
|
+
|
55
|
+
class TestNode(BaseNode):
|
56
|
+
pass
|
57
|
+
|
58
|
+
# WHEN we use trigger >> node syntax
|
59
|
+
graph = TestTrigger >> TestNode
|
60
|
+
|
61
|
+
# THEN a graph is created
|
62
|
+
assert graph is not None
|
63
|
+
assert len(list(graph.trigger_edges)) == 1
|
64
|
+
assert list(graph.trigger_edges)[0].trigger_class == TestTrigger
|
65
|
+
assert list(graph.trigger_edges)[0].to_node == TestNode
|
66
|
+
|
67
|
+
|
68
|
+
def test_integration_trigger__multiple_entrypoints():
|
69
|
+
"""IntegrationTrigger works with multiple entry points."""
|
70
|
+
|
71
|
+
# GIVEN a trigger and multiple nodes
|
72
|
+
class TestTrigger(IntegrationTrigger):
|
73
|
+
class Outputs(IntegrationTrigger.Outputs):
|
74
|
+
msg: str
|
75
|
+
|
76
|
+
@classmethod
|
77
|
+
def process_event(cls, event_data: dict):
|
78
|
+
return cls.Outputs(msg=event_data.get("msg", ""))
|
79
|
+
|
80
|
+
class NodeA(BaseNode):
|
81
|
+
pass
|
82
|
+
|
83
|
+
class NodeB(BaseNode):
|
84
|
+
pass
|
85
|
+
|
86
|
+
# WHEN we use trigger >> {nodes} syntax
|
87
|
+
graph = TestTrigger >> {NodeA, NodeB}
|
88
|
+
|
89
|
+
# THEN both nodes are entrypoints
|
90
|
+
trigger_edges = list(graph.trigger_edges)
|
91
|
+
assert len(trigger_edges) == 2
|
92
|
+
target_nodes = {edge.to_node for edge in trigger_edges}
|
93
|
+
assert target_nodes == {NodeA, NodeB}
|
94
|
+
|
95
|
+
|
96
|
+
def test_integration_trigger__config_attribute():
|
97
|
+
"""IntegrationTrigger has optional config attribute."""
|
98
|
+
|
99
|
+
# GIVEN IntegrationTrigger
|
100
|
+
# THEN it has a config class variable
|
101
|
+
assert hasattr(IntegrationTrigger, "config")
|
102
|
+
assert IntegrationTrigger.config is None
|
@@ -26,6 +26,8 @@ from typing import (
|
|
26
26
|
overload,
|
27
27
|
)
|
28
28
|
|
29
|
+
from pydantic import ValidationError
|
30
|
+
|
29
31
|
from vellum.workflows.edges import Edge
|
30
32
|
from vellum.workflows.emitters.base import BaseWorkflowEmitter
|
31
33
|
from vellum.workflows.errors import WorkflowError, WorkflowErrorCode
|
@@ -684,6 +686,10 @@ class BaseWorkflow(Generic[InputsType, StateType], BaseExecutable, metaclass=_Ba
|
|
684
686
|
workflow_path = f"{module_path}.workflow"
|
685
687
|
try:
|
686
688
|
module = importlib.import_module(workflow_path)
|
689
|
+
except ValidationError as e:
|
690
|
+
raise WorkflowInitializationException(
|
691
|
+
message=f"Pydantic Model Validation defined in Workflow Failed: {e}"
|
692
|
+
) from e
|
687
693
|
except TypeError as e:
|
688
694
|
if "Unexpected graph type" in str(e) or "unhashable type: 'set'" in str(e):
|
689
695
|
raise WorkflowInitializationException(
|
@@ -691,9 +697,17 @@ class BaseWorkflow(Generic[InputsType, StateType], BaseExecutable, metaclass=_Ba
|
|
691
697
|
"Please contact Vellum support for assistance with Workflow configuration."
|
692
698
|
) from e
|
693
699
|
else:
|
694
|
-
raise
|
695
|
-
except
|
696
|
-
raise WorkflowInitializationException(message=f"
|
700
|
+
raise WorkflowInitializationException(message=f"Type Error raised while loading Workflow: {e}") from e
|
701
|
+
except SyntaxError as e:
|
702
|
+
raise WorkflowInitializationException(message=f"Syntax Error raised while loading Workflow: {e}") from e
|
703
|
+
except ModuleNotFoundError as e:
|
704
|
+
raise WorkflowInitializationException(message=f"Workflow module not found: {e}") from e
|
705
|
+
except ImportError as e:
|
706
|
+
raise WorkflowInitializationException(message=f"Invalid import found while loading Workflow: {e}") from e
|
707
|
+
except NameError as e:
|
708
|
+
raise WorkflowInitializationException(message=f"Invalid variable reference: {e}") from e
|
709
|
+
except Exception as e:
|
710
|
+
raise WorkflowInitializationException(message=f"Unexpected failure while loading module: {e}") from e
|
697
711
|
workflows: List[Type[BaseWorkflow]] = []
|
698
712
|
for name in dir(module):
|
699
713
|
if name.startswith("__"):
|
@@ -9,7 +9,7 @@ vellum_cli/logger.py,sha256=dcM_OmgqXLo93vDYswO5ylyUQQcTfnA5GTd5tbIt3wM,1446
|
|
9
9
|
vellum_cli/move.py,sha256=lCHQ-U4BspgS512GxFFvUrglitaHkWfuKn1Hpfcn7-Q,2053
|
10
10
|
vellum_cli/ping.py,sha256=p_BCCRjgPhng6JktuECtkDQLbhopt6JpmrtGoLnLJT8,1161
|
11
11
|
vellum_cli/pull.py,sha256=udYyPlJ6VKDdh78rApNJOZgxHl82fcV6iGnRPSdX1LY,14750
|
12
|
-
vellum_cli/push.py,sha256=
|
12
|
+
vellum_cli/push.py,sha256=epoQNdFdXUzLlfwE2ZTklfy3DW6bI4-Pgv1QRS8CZXk,11803
|
13
13
|
vellum_cli/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
14
|
vellum_cli/tests/conftest.py,sha256=wx3PlJjVB0HRf5dr2b_idOIw27WPPl0J0FNbhIJJaVk,1689
|
15
15
|
vellum_cli/tests/test_config.py,sha256=uvKGDc8BoVyT9_H0Z-g8469zVxomn6Oi3Zj-vK7O_wU,2631
|
@@ -20,7 +20,7 @@ vellum_cli/tests/test_main.py,sha256=qDZG-aQauPwBwM6A2DIu1494n47v3pL28XakTbLGZ-k
|
|
20
20
|
vellum_cli/tests/test_move.py,sha256=FIrL1xlH5oFKGX2MugcTKL8JilpopmUC7hP5OaqF5zw,5213
|
21
21
|
vellum_cli/tests/test_ping.py,sha256=b3aQLd-N59_8w2rRiWqwpB1rlHaKEYVbAj1Y3hi7A-g,2605
|
22
22
|
vellum_cli/tests/test_pull.py,sha256=e2XHzcHIx9k-FyuNAl7wMSNsSSebPGyP6U05JGcddFs,49447
|
23
|
-
vellum_cli/tests/test_push.py,sha256=
|
23
|
+
vellum_cli/tests/test_push.py,sha256=oQ3x28G6IxplmMWCcPEYY46nOYAEPaihcMVsN4quQ5Q,45000
|
24
24
|
vellum_ee/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
25
|
vellum_ee/assets/node-definitions.json,sha256=Mm3c1nfEa1QjWWzNvIJlhahDcY4SM3wQm8og_x3jyd8,30755
|
26
26
|
vellum_ee/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -32,7 +32,7 @@ vellum_ee/workflows/display/editor/__init__.py,sha256=MSAgY91xCEg2neH5d8jXx5wRdR
|
|
32
32
|
vellum_ee/workflows/display/editor/types.py,sha256=rmaNXkNZUNRgK-mJJ_g1-Fm3OGxoQfqEB7zn-zzgJtc,664
|
33
33
|
vellum_ee/workflows/display/exceptions.py,sha256=_FDhK-lfuBPHY2GSywp70ewM0k55Ji5Bp-wZlEZenz4,112
|
34
34
|
vellum_ee/workflows/display/nodes/__init__.py,sha256=jI1aPBQf8DkmrYoZ4O-wR1duqZByOf5mDFmo_wFJPE4,307
|
35
|
-
vellum_ee/workflows/display/nodes/base_node_display.py,sha256=
|
35
|
+
vellum_ee/workflows/display/nodes/base_node_display.py,sha256=ceKQdHZmDSOY5-M2DtJnuLbdkuFujCChFtRABDoV1jo,19497
|
36
36
|
vellum_ee/workflows/display/nodes/get_node_display_class.py,sha256=jI_kUi9LnNLDpY63QtlC4TfN8P571VN4LpzH0I1ZtLk,1149
|
37
37
|
vellum_ee/workflows/display/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
38
|
vellum_ee/workflows/display/nodes/tests/test_base_node_display.py,sha256=JLa9nlG38dLfCo1Y8ISsJ21hrfDyy4-ae3pZ9H01yFs,5578
|
@@ -80,7 +80,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/__init__.py,sha256=47DE
|
|
80
80
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
81
81
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py,sha256=Y-ajeT65b5varmrZCw6L3hir4hJCFq-eO0jZfRcrs7g,1886
|
82
82
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py,sha256=wdVaFvxicj48Kj-6VUlu61KR0oSArLTjownRi2p0NWQ,14941
|
83
|
-
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py,sha256=
|
83
|
+
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py,sha256=rDh6PxhdoVDNuKdUrtZpoMtX8T92ZUMonkVxDjeEE4g,25507
|
84
84
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py,sha256=SwXRzjdoEZLvkzaRMvRV8_UqbBm0EB_UtAHD_zXKZBY,6303
|
85
85
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py,sha256=jubGYgLJImOqILd5LjnYJ4B1UMIrToDrQbPZOvaQCX4,40035
|
86
86
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py,sha256=FLvcD8eoABHUPv08oSpIp_P-65sw2gl4whMXEJJj4f8,6785
|
@@ -110,7 +110,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling
|
|
110
110
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py,sha256=pLCyMScV88DTBXRH7jXaXOEA1GBq8NIipCUFwIAWnwI,2771
|
111
111
|
vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py,sha256=exT7U-axwtYgFylagScflSQLJEND51qIAx2UATju6JM,6023
|
112
112
|
vellum_ee/workflows/display/tests/workflow_serialization/test_final_output_node_map_reference_serialization.py,sha256=vl3pxUJlrYRA8zzFJ-gRm7fe-5fviLNSIsUC7imnMqk,3502
|
113
|
-
vellum_ee/workflows/display/tests/workflow_serialization/test_manual_trigger_serialization.py,sha256=
|
113
|
+
vellum_ee/workflows/display/tests/workflow_serialization/test_manual_trigger_serialization.py,sha256=sd0lbity6yVIJ3HbMZEcL1wJEYoihqVW2Bjx8YMmrAM,3657
|
114
114
|
vellum_ee/workflows/display/tests/workflow_serialization/test_terminal_node_any_serialization.py,sha256=4WAmSEJZlDBLPhsD1f4GwY9ahB9F6qJKGnL6j7ZYlzQ,1740
|
115
115
|
vellum_ee/workflows/display/tests/workflow_serialization/test_web_search_node_serialization.py,sha256=vbDFBrWUPeeW7cxjNA6SXrsHlYcbOAhlQ4C45Vdnr1c,3428
|
116
116
|
vellum_ee/workflows/display/tests/workflow_serialization/test_workflow_input_parameterization_error.py,sha256=vAdmn3YTBDpo55znbydQxsgg9ASqHcvsUPwiBR_7wfo,1461
|
@@ -119,7 +119,7 @@ vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
|
|
119
119
|
vellum_ee/workflows/display/utils/auto_layout.py,sha256=f4GiLn_LazweupfqTpubcdtdfE_vrOcmZudSsnYIY9E,3906
|
120
120
|
vellum_ee/workflows/display/utils/events.py,sha256=DE33uoKW78BZtITJ6L22dMZN3KR1BuZBVC98C_gIyzU,1943
|
121
121
|
vellum_ee/workflows/display/utils/exceptions.py,sha256=E8Lvo7LY1BoZ54M_NR_opDjJsAAiCUfow1HgoHcTHmg,989
|
122
|
-
vellum_ee/workflows/display/utils/expressions.py,sha256=
|
122
|
+
vellum_ee/workflows/display/utils/expressions.py,sha256=IIieWILv2zGLYTRgeDwgjhtga1ttV-ss2remJ1HBVXA,20688
|
123
123
|
vellum_ee/workflows/display/utils/registry.py,sha256=1qXiBTdsnro6FeCX0FGBEK7CIf6wa--Jt50iZ_nEp_M,3460
|
124
124
|
vellum_ee/workflows/display/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
125
125
|
vellum_ee/workflows/display/utils/tests/test_auto_layout.py,sha256=vfXI769418s9vda5Gb5NFBH747WMOwSgHRXeLCTLVm8,2356
|
@@ -127,7 +127,7 @@ vellum_ee/workflows/display/utils/tests/test_events.py,sha256=42IEBnMbaQrH8gigw5
|
|
127
127
|
vellum_ee/workflows/display/utils/vellum.py,sha256=Bt7kdLdXoBsHn5dVEY2uKcF542VL09jwu8J_30rl2vk,6413
|
128
128
|
vellum_ee/workflows/display/vellum.py,sha256=J2mdJZ1sdLW535DDUkq_Vm8Z572vhuxHxVZF9deKSdk,391
|
129
129
|
vellum_ee/workflows/display/workflows/__init__.py,sha256=JTB9ObEV3l4gGGdtfBHwVJtTTKC22uj-a-XjTVwXCyA,148
|
130
|
-
vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=
|
130
|
+
vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=DAGqGCg2WTBTNeO1akDpeCAJ5sAtUu65dnXsagnO6Jk,46937
|
131
131
|
vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=gxz76AeCqgAZ9D2lZeTiZzxY9eMgn3qOSfVgiqYcOh8,2028
|
132
132
|
vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=lg-c_3P3ldtqWq2VFsk_2Mkn3pVdXWuT59QpH7QwXVs,39764
|
133
133
|
vellum_ee/workflows/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -154,14 +154,14 @@ vellum_ee/workflows/tests/local_workflow/workflow.py,sha256=A4qOzOPNwePYxWbcAgIP
|
|
154
154
|
vellum_ee/workflows/tests/test_display_meta.py,sha256=PkXJVnMZs9GNooDkd59n4YTBAX3XGPQWeSSVbhehVFM,5112
|
155
155
|
vellum_ee/workflows/tests/test_registry.py,sha256=B8xRIuEyLWfSqrYoPldNQXhKPfe50PllvtAZoI8-uPs,6066
|
156
156
|
vellum_ee/workflows/tests/test_serialize_module.py,sha256=zleQTcGZa5_nzwu4zpFoqEHhk7pb64hGrhObR4anhPQ,4471
|
157
|
-
vellum_ee/workflows/tests/test_server.py,sha256=
|
157
|
+
vellum_ee/workflows/tests/test_server.py,sha256=RmLE2s9Cs7NejvWf7aPRNuAeEER-hGk-9Q9fYrn5wps,26013
|
158
158
|
vellum_ee/workflows/tests/test_virtual_files.py,sha256=TJEcMR0v2S8CkloXNmCHA0QW0K6pYNGaIjraJz7sFvY,2762
|
159
159
|
vellum/__init__.py,sha256=6dkyRHmIKuQPzL_z3QLVUrbkAF-HJKDhDSMCnf4ZsKw,49502
|
160
160
|
vellum/client/README.md,sha256=flqu57ubZNTfpq60CdLtJC9gp4WEkyjb_n_eZ4OYf9w,6497
|
161
161
|
vellum/client/__init__.py,sha256=rMnKRqL5-356SBc-rfm56MkO87PuAi2mtcfBszcJU1M,74316
|
162
162
|
vellum/client/core/__init__.py,sha256=lTcqUPXcx4112yLDd70RAPeqq6tu3eFMe1pKOqkW9JQ,1562
|
163
163
|
vellum/client/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
|
164
|
-
vellum/client/core/client_wrapper.py,sha256=
|
164
|
+
vellum/client/core/client_wrapper.py,sha256=A3sL2WdcS11xGFV5Yq5h9yzf-96DpP7AL8dayvAKlUk,2840
|
165
165
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
166
166
|
vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
|
167
167
|
vellum/client/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
|
@@ -1885,8 +1885,8 @@ vellum/workflows/integrations/vellum_integration_service.py,sha256=qhFoLzHlMli1P
|
|
1885
1885
|
vellum/workflows/logging.py,sha256=_a217XogktV4Ncz6xKFz7WfYmZAzkfVRVuC0rWob8ls,437
|
1886
1886
|
vellum/workflows/nodes/__init__.py,sha256=zymtc3_iW2rFmMR-sayTLuN6ZsAw8VnJweWPsjQk2-Q,1197
|
1887
1887
|
vellum/workflows/nodes/bases/__init__.py,sha256=cniHuz_RXdJ4TQgD8CBzoiKDiPxg62ErdVpCbWICX64,58
|
1888
|
-
vellum/workflows/nodes/bases/base.py,sha256=
|
1889
|
-
vellum/workflows/nodes/bases/base_adornment_node.py,sha256=
|
1888
|
+
vellum/workflows/nodes/bases/base.py,sha256=u7NmYWhQZm91KZV53PGD-gpZvcWAItOme95TjZkHwDI,22094
|
1889
|
+
vellum/workflows/nodes/bases/base_adornment_node.py,sha256=TgL-tfX84GyTb7ONQ2z7OJDkx57kW3qbQNDuiw-Zrqo,5814
|
1890
1890
|
vellum/workflows/nodes/bases/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1891
1891
|
vellum/workflows/nodes/bases/tests/test_base_adornment_node.py,sha256=fXZI9KqpS4XMBrBnIEkK3foHaBVvyHwYcQWWDKay7ic,1148
|
1892
1892
|
vellum/workflows/nodes/bases/tests/test_base_node.py,sha256=igJrcSxSZADk5tLpssAt0uAXe9oJoLbilzueJJvA5p4,10942
|
@@ -1925,7 +1925,7 @@ vellum/workflows/nodes/displayable/bases/api_node/tests/test_node.py,sha256=5C59
|
|
1925
1925
|
vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py,sha256=Org3xTvgp1pA0uUXFfnJr29D3HzCey2lEdYF4zbIUgo,70
|
1926
1926
|
vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=w02vgydiwNoKru324QLSkH3BiGUvHTgKbf05BEx945s,4657
|
1927
1927
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py,sha256=Hl35IAoepRpE-j4cALaXVJIYTYOF3qszyVbxTj4kS1s,82
|
1928
|
-
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=
|
1928
|
+
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=ITxAa1HWF6OPdcKg0DdTK7YP94ezzzWVyZzCRMiybIg,18638
|
1929
1929
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1930
1930
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py,sha256=xc53wGwVqxBnN7eoyWkJ-RJ-FeUpHKekkKjViASHAFg,27495
|
1931
1931
|
vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py,sha256=H9mM75EQpP6PUvsXCTbwjw4CqMMLf36m1G2XqiPEvH4,12139
|
@@ -1966,13 +1966,13 @@ vellum/workflows/nodes/displayable/prompt_deployment_node/node.py,sha256=XeBn6d3
|
|
1966
1966
|
vellum/workflows/nodes/displayable/prompt_deployment_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1967
1967
|
vellum/workflows/nodes/displayable/prompt_deployment_node/tests/test_node.py,sha256=c_nuuqrwiIjgj4qIbVypfDuOc-3TlgO6CbXFqQl2Nqw,19725
|
1968
1968
|
vellum/workflows/nodes/displayable/search_node/__init__.py,sha256=hpBpvbrDYf43DElRZFLzieSn8weXiwNiiNOJurERQbs,62
|
1969
|
-
vellum/workflows/nodes/displayable/search_node/node.py,sha256=
|
1969
|
+
vellum/workflows/nodes/displayable/search_node/node.py,sha256=hbPsZhyXfq9dx0mfBKOyivluDmV2iXmDTT7loEyu9nI,2057
|
1970
1970
|
vellum/workflows/nodes/displayable/search_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1971
|
-
vellum/workflows/nodes/displayable/search_node/tests/test_node.py,sha256=
|
1971
|
+
vellum/workflows/nodes/displayable/search_node/tests/test_node.py,sha256=YXgIIAJHVQxrfyJ0gxeJC0fAJaic10_zbqvsS8hyZSc,9368
|
1972
1972
|
vellum/workflows/nodes/displayable/subworkflow_deployment_node/__init__.py,sha256=9yYM6001YZeqI1VOk1QuEM_yrffk_EdsO7qaPzINKds,92
|
1973
|
-
vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py,sha256=
|
1973
|
+
vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py,sha256=AHlW7aPDza1FuSR_9xONOe3tzDFDg8EIJtO1NJ7ILhk,14445
|
1974
1974
|
vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1975
|
-
vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py,sha256=
|
1975
|
+
vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py,sha256=PII44speqT4fJvj60y_3KDAnH1L6Ivtq9R4BykY-X_A,19092
|
1976
1976
|
vellum/workflows/nodes/displayable/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1977
1977
|
vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py,sha256=E6PQ9OKcDlsJbWoxVKWgiAPgz9p59g1ONMgNggfOeiI,4868
|
1978
1978
|
vellum/workflows/nodes/displayable/tests/test_search_node_error_handling.py,sha256=8aw8hDFL0ZXThvAa7yxrJN026EYGD4-Q1si3Phu9-_0,6307
|
@@ -1983,9 +1983,9 @@ vellum/workflows/nodes/displayable/tool_calling_node/node.py,sha256=rvCGtnCM1bFk
|
|
1983
1983
|
vellum/workflows/nodes/displayable/tool_calling_node/state.py,sha256=CcBVb_YtwfSSka4ze678k6-qwmzMSfjfVP8_Y95feSo,302
|
1984
1984
|
vellum/workflows/nodes/displayable/tool_calling_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1985
1985
|
vellum/workflows/nodes/displayable/tool_calling_node/tests/test_composio_service.py,sha256=in1fbEz5x1tx3uKv9YXdvOncsHucNL8Ro6Go7lBuuOQ,8962
|
1986
|
-
vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py,sha256=
|
1986
|
+
vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py,sha256=uXz9tbPK6ikGlF8Tfx-qiPeF-8qq_E5ZbmCmOMWkz24,15506
|
1987
1987
|
vellum/workflows/nodes/displayable/tool_calling_node/tests/test_utils.py,sha256=EmKFA-ELdTzlK0xMqWnuSZPoGNLYCwk6b0amTqirZo0,11305
|
1988
|
-
vellum/workflows/nodes/displayable/tool_calling_node/utils.py,sha256=
|
1988
|
+
vellum/workflows/nodes/displayable/tool_calling_node/utils.py,sha256=sReCkqd2pwUQ6pX9xZ_zQh-Wza2_2eV7HYRAHYaAaHo,24580
|
1989
1989
|
vellum/workflows/nodes/displayable/web_search_node/__init__.py,sha256=8FOnEP-n-U68cvxTlJW9wphIAGHq5aqjzLM-DoSSXnU,61
|
1990
1990
|
vellum/workflows/nodes/displayable/web_search_node/node.py,sha256=NQYux2bOtuBF5E4tn-fXi5y3btURPRrNqMSM9MAZYI4,5091
|
1991
1991
|
vellum/workflows/nodes/displayable/web_search_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -2025,7 +2025,7 @@ vellum/workflows/resolvers/resolver.py,sha256=3uEYscB_2PHTazc0Y9SzOe_yiQZhVLfey1
|
|
2025
2025
|
vellum/workflows/resolvers/tests/test_resolver.py,sha256=PnUGzsulo1It_LjjhHsRNiILvvl5G_IaK8ZX56zKC28,6204
|
2026
2026
|
vellum/workflows/resolvers/types.py,sha256=Hndhlk69g6EKLh_LYg5ILepW5U_h_BYNllfzhS9k8p4,237
|
2027
2027
|
vellum/workflows/runner/__init__.py,sha256=i1iG5sAhtpdsrlvwgH6B-m49JsINkiWyPWs8vyT-bqM,72
|
2028
|
-
vellum/workflows/runner/runner.py,sha256=
|
2028
|
+
vellum/workflows/runner/runner.py,sha256=IYjeFx6_jescg8tEW-et5k96X9EsB6PDw4Kw4Qvy-Xo,45599
|
2029
2029
|
vellum/workflows/sandbox.py,sha256=mezSZmilR_fwR8164n8CEfzlMeQ55IqfapHp4ftImvQ,3212
|
2030
2030
|
vellum/workflows/state/__init__.py,sha256=yUUdR-_Vl7UiixNDYQZ-GEM_kJI9dnOia75TtuNEsnE,60
|
2031
2031
|
vellum/workflows/state/base.py,sha256=A8s0PC8UvFjPpkHDY6u-yIeb2KHjoAmu-GW-GYrDl0E,24654
|
@@ -2039,9 +2039,12 @@ vellum/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
2039
2039
|
vellum/workflows/tests/test_dataset_row.py,sha256=S8aIiYU9TRzJ8GTl5qCjnJ-fuHdxatHJFGLlKTVHPr4,4174
|
2040
2040
|
vellum/workflows/tests/test_sandbox.py,sha256=JKwaluI-lODQo7Ek9sjDstjL_WTdSqUlVik6ZVTfVOA,1826
|
2041
2041
|
vellum/workflows/tests/test_undefined.py,sha256=zMCVliCXVNLrlC6hEGyOWDnQADJ2g83yc5FIM33zuo8,353
|
2042
|
-
vellum/workflows/triggers/__init__.py,sha256=
|
2042
|
+
vellum/workflows/triggers/__init__.py,sha256=kistj6wgRgYe3fO82_4giZ_xFkElfnsDGRKAbzxrGnc,249
|
2043
2043
|
vellum/workflows/triggers/base.py,sha256=HIZkKPdb9GOYjpGzk2DoSqkxsUyjBnzmsLyhVTWm1iE,4857
|
2044
|
+
vellum/workflows/triggers/integration.py,sha256=_RyNrNnIBIa08FMHmLh2QEZPb-u5j75Bye_FbR82nkg,2043
|
2044
2045
|
vellum/workflows/triggers/manual.py,sha256=PgbZ92gcK25yz6REXm98zWic1QBfhxLKfGCeHpZEUx4,1266
|
2046
|
+
vellum/workflows/triggers/tests/__init__.py,sha256=R8lag_iCRyulijHMK4e3Gf6YVB5NplfvwZeTkaRj8gQ,30
|
2047
|
+
vellum/workflows/triggers/tests/test_integration.py,sha256=5N7ejz4AFmgQAZlHGV466rzWyb79iLeXU-pAfx9o4TA,3213
|
2045
2048
|
vellum/workflows/types/__init__.py,sha256=fZ3Xxly7YSsu4kCIYD5aYpYucNM97zTyInb9CA24mf0,102
|
2046
2049
|
vellum/workflows/types/code_execution_node_wrappers.py,sha256=fewX9bqF_4TZuK-gZYIn12s31-k03vHMGRpvFAPm11Y,3206
|
2047
2050
|
vellum/workflows/types/core.py,sha256=R7snCd7ci4tiRuHi5ALGh_5DIIF0T9eze3sf6EnJN-c,1126
|
@@ -2067,13 +2070,13 @@ vellum/workflows/utils/vellum_variables.py,sha256=X3lZn-EoWengRWBWRhTNW7hqbj7LkV
|
|
2067
2070
|
vellum/workflows/utils/zip.py,sha256=HVg_YZLmBOTXKaDV3Xhaf3V6sYnfqqZXQ8CpuafkbPY,1181
|
2068
2071
|
vellum/workflows/vellum_client.py,sha256=3iDR7VV_NgLSm1iZQCKDvrmfEaX1bOJiU15QrxyHpv0,1237
|
2069
2072
|
vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
|
2070
|
-
vellum/workflows/workflows/base.py,sha256=
|
2073
|
+
vellum/workflows/workflows/base.py,sha256=2XQMntFPXUO3p1js14TEKun4oNWRmZOzga-pUiv5vVk,30935
|
2071
2074
|
vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
|
2072
2075
|
vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2073
2076
|
vellum/workflows/workflows/tests/test_base_workflow.py,sha256=Boa-_m9ii2Qsa1RvVM-VYniF7zCpzGgEGy-OnPZkrHg,23941
|
2074
2077
|
vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
|
2075
|
-
vellum_ai-1.7.
|
2076
|
-
vellum_ai-1.7.
|
2077
|
-
vellum_ai-1.7.
|
2078
|
-
vellum_ai-1.7.
|
2079
|
-
vellum_ai-1.7.
|
2078
|
+
vellum_ai-1.7.7.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
2079
|
+
vellum_ai-1.7.7.dist-info/METADATA,sha256=AUowwbBfQrczLwFHQeRVeZoiVw6lIuKUlK52uh9Qb6o,5547
|
2080
|
+
vellum_ai-1.7.7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
2081
|
+
vellum_ai-1.7.7.dist-info/entry_points.txt,sha256=xVavzAKN4iF_NbmhWOlOkHluka0YLkbN_pFQ9pW3gLI,117
|
2082
|
+
vellum_ai-1.7.7.dist-info/RECORD,,
|
vellum_cli/push.py
CHANGED
@@ -77,11 +77,7 @@ def push_command(
|
|
77
77
|
|
78
78
|
logger.info(f"Loading workflow from {workflow_config.module}")
|
79
79
|
resolved_workspace = workspace or workflow_config.workspace or DEFAULT_WORKSPACE_CONFIG.name
|
80
|
-
workspace_config = (
|
81
|
-
next((w for w in config.workspaces if w.name == resolved_workspace), DEFAULT_WORKSPACE_CONFIG)
|
82
|
-
if workspace
|
83
|
-
else DEFAULT_WORKSPACE_CONFIG
|
84
|
-
)
|
80
|
+
workspace_config = next((w for w in config.workspaces if w.name == resolved_workspace), DEFAULT_WORKSPACE_CONFIG)
|
85
81
|
api_key = os.getenv(workspace_config.api_key)
|
86
82
|
if not api_key:
|
87
83
|
raise ValueError(f"No API key value found in environment for workspace '{workspace_config.name}'.")
|
vellum_cli/tests/test_push.py
CHANGED
@@ -1134,3 +1134,89 @@ def test_push__deploy_stores_deployment_config_in_lock_file(mock_module, vellum_
|
|
1134
1134
|
deployment_config_str = call_args["deployment_config"]
|
1135
1135
|
deployment_config = json.loads(deployment_config_str)
|
1136
1136
|
assert deployment_config["name"] == "test-push-deploy-stores-deployment-config-in-lock-file"
|
1137
|
+
|
1138
|
+
|
1139
|
+
def test_push__custom_workspace_in_lockfile__uses_custom_workspace_without_flag(mock_module, vellum_client_class):
|
1140
|
+
"""
|
1141
|
+
Tests that push respects the custom workspace from the lockfile when no --workspace flag is provided.
|
1142
|
+
"""
|
1143
|
+
|
1144
|
+
# GIVEN a workflow already configured in the lockfile with a custom workspace
|
1145
|
+
temp_dir = mock_module.temp_dir
|
1146
|
+
module = mock_module.module
|
1147
|
+
workflow_sandbox_id = mock_module.workflow_sandbox_id
|
1148
|
+
set_pyproject_toml = mock_module.set_pyproject_toml
|
1149
|
+
|
1150
|
+
# AND the lockfile has the workflow with a custom workspace
|
1151
|
+
with open(os.path.join(temp_dir, "vellum.lock.json"), "w") as f:
|
1152
|
+
json.dump(
|
1153
|
+
{
|
1154
|
+
"version": "1.0",
|
1155
|
+
"workflows": [
|
1156
|
+
{
|
1157
|
+
"module": module,
|
1158
|
+
"workflow_sandbox_id": workflow_sandbox_id,
|
1159
|
+
"workspace": "my_custom_workspace",
|
1160
|
+
"container_image_name": None,
|
1161
|
+
"container_image_tag": None,
|
1162
|
+
"deployments": [],
|
1163
|
+
"ignore": None,
|
1164
|
+
"target_directory": None,
|
1165
|
+
}
|
1166
|
+
],
|
1167
|
+
"workspaces": [],
|
1168
|
+
},
|
1169
|
+
f,
|
1170
|
+
indent=2,
|
1171
|
+
)
|
1172
|
+
|
1173
|
+
# AND the custom workspace is defined in pyproject.toml
|
1174
|
+
set_pyproject_toml(
|
1175
|
+
{
|
1176
|
+
"workflows": [],
|
1177
|
+
"workspaces": [
|
1178
|
+
{
|
1179
|
+
"name": "my_custom_workspace",
|
1180
|
+
"api_key": "MY_CUSTOM_VELLUM_API_KEY",
|
1181
|
+
}
|
1182
|
+
],
|
1183
|
+
}
|
1184
|
+
)
|
1185
|
+
|
1186
|
+
# AND the .env file has the custom api key
|
1187
|
+
with open(os.path.join(temp_dir, ".env"), "w") as f:
|
1188
|
+
f.write(
|
1189
|
+
"""\
|
1190
|
+
VELLUM_API_KEY=abcdef123456
|
1191
|
+
MY_CUSTOM_VELLUM_API_KEY=custom-key-xyz
|
1192
|
+
"""
|
1193
|
+
)
|
1194
|
+
|
1195
|
+
# AND a workflow exists in the module
|
1196
|
+
_ensure_workflow_py(temp_dir, module)
|
1197
|
+
|
1198
|
+
# AND the push API returns successfully
|
1199
|
+
vellum_client_class.return_value.workflows.push.return_value = WorkflowPushResponse(
|
1200
|
+
workflow_sandbox_id=workflow_sandbox_id,
|
1201
|
+
)
|
1202
|
+
vellum_client_class.return_value._client_wrapper._environment.default = "https://api.vellum.ai/v1"
|
1203
|
+
|
1204
|
+
# WHEN calling `vellum push` WITHOUT the --workspace flag
|
1205
|
+
runner = CliRunner()
|
1206
|
+
result = runner.invoke(cli_main, ["push", module])
|
1207
|
+
|
1208
|
+
# THEN it should succeed
|
1209
|
+
assert result.exit_code == 0, result.output
|
1210
|
+
|
1211
|
+
# AND the custom workspace API key should have been used
|
1212
|
+
vellum_client_class.assert_called_once_with(
|
1213
|
+
api_key="custom-key-xyz",
|
1214
|
+
environment=mock.ANY,
|
1215
|
+
api_version=None,
|
1216
|
+
)
|
1217
|
+
|
1218
|
+
with open(os.path.join(temp_dir, "vellum.lock.json")) as f:
|
1219
|
+
lock_file_content = json.load(f)
|
1220
|
+
assert len(lock_file_content["workflows"]) == 1
|
1221
|
+
assert lock_file_content["workflows"][0]["workspace"] == "my_custom_workspace"
|
1222
|
+
assert lock_file_content["workflows"][0]["workflow_sandbox_id"] == workflow_sandbox_id
|
@@ -188,7 +188,7 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
|
|
188
188
|
type = primitive_type_to_vellum_variable_type(output)
|
189
189
|
value = (
|
190
190
|
serialize_value(node_id, display_context, output.instance)
|
191
|
-
if output.instance is not None and output.instance
|
191
|
+
if output.instance is not None and output.instance is not undefined
|
192
192
|
else None
|
193
193
|
)
|
194
194
|
|
@@ -688,3 +688,19 @@ def test_serialize_node__comment_expanded_preserved_when_explicitly_set(serializ
|
|
688
688
|
assert "comment" in display_data
|
689
689
|
assert display_data["comment"]["value"] == "This is a test comment."
|
690
690
|
assert display_data["comment"]["expanded"] is False
|
691
|
+
|
692
|
+
|
693
|
+
def test_serialize_node__attribute_with_type_annotation_no_default(serialize_node):
|
694
|
+
"""
|
695
|
+
Tests that attributes with type annotations but no default values serialize as None.
|
696
|
+
"""
|
697
|
+
|
698
|
+
# GIVEN a node with typed attributes but no default values
|
699
|
+
class NodeWithTypedAttributesNoDefault(BaseNode):
|
700
|
+
attr: str
|
701
|
+
|
702
|
+
# WHEN the node is serialized
|
703
|
+
serialized_node = serialize_node(NodeWithTypedAttributesNoDefault)
|
704
|
+
|
705
|
+
# THEN the attribute should serialize as None
|
706
|
+
assert serialized_node["attributes"][0]["value"] is None
|
vellum_ee/workflows/display/tests/workflow_serialization/test_manual_trigger_serialization.py
CHANGED
@@ -3,8 +3,6 @@
|
|
3
3
|
import pytest
|
4
4
|
from typing import cast
|
5
5
|
|
6
|
-
from deepdiff import DeepDiff
|
7
|
-
|
8
6
|
from vellum.workflows import BaseWorkflow
|
9
7
|
from vellum.workflows.inputs.base import BaseInputs
|
10
8
|
from vellum.workflows.nodes.bases.base import BaseNode
|
@@ -42,27 +40,24 @@ def serialize(workflow_class) -> JsonObject:
|
|
42
40
|
|
43
41
|
|
44
42
|
def test_manual_trigger_serialization():
|
45
|
-
"""Workflow with ManualTrigger serializes with
|
43
|
+
"""Workflow with ManualTrigger serializes with triggers field."""
|
46
44
|
result = serialize(create_workflow(ManualTrigger))
|
47
|
-
|
48
|
-
|
45
|
+
triggers = cast(JsonArray, result["triggers"])
|
46
|
+
|
47
|
+
assert len(triggers) == 1
|
48
|
+
trigger = cast(JsonObject, triggers[0])
|
49
49
|
|
50
50
|
assert trigger["type"] == "MANUAL"
|
51
|
-
assert
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
},
|
56
|
-
trigger,
|
57
|
-
ignore_order=True,
|
58
|
-
)
|
51
|
+
assert "id" in trigger
|
52
|
+
assert "attributes" in trigger
|
53
|
+
assert trigger["attributes"] == []
|
54
|
+
assert "definition" not in trigger
|
59
55
|
|
60
56
|
|
61
57
|
def test_no_trigger_serialization():
|
62
|
-
"""Workflow without trigger has no
|
58
|
+
"""Workflow without trigger has no triggers field."""
|
63
59
|
result = serialize(create_workflow())
|
64
|
-
|
65
|
-
assert "trigger" not in workflow_raw_data
|
60
|
+
assert "triggers" not in result
|
66
61
|
|
67
62
|
|
68
63
|
def test_manual_trigger_multiple_entrypoints():
|
@@ -84,10 +79,12 @@ def test_manual_trigger_multiple_entrypoints():
|
|
84
79
|
output_b = NodeB.Outputs.output
|
85
80
|
|
86
81
|
result = serialize(MultiWorkflow)
|
82
|
+
triggers = cast(JsonArray, result["triggers"])
|
87
83
|
workflow_data = cast(JsonObject, result["workflow_raw_data"])
|
88
|
-
trigger = cast(JsonObject, workflow_data["trigger"])
|
89
84
|
nodes = cast(JsonArray, workflow_data["nodes"])
|
90
85
|
|
86
|
+
assert len(triggers) == 1
|
87
|
+
trigger = cast(JsonObject, triggers[0])
|
91
88
|
assert trigger["type"] == "MANUAL"
|
92
89
|
assert len([n for n in nodes if cast(JsonObject, n)["type"] == "GENERIC"]) >= 2
|
93
90
|
|
@@ -98,8 +95,8 @@ def test_serialized_workflow_structure():
|
|
98
95
|
workflow_raw_data = cast(JsonObject, result["workflow_raw_data"])
|
99
96
|
definition = cast(JsonObject, workflow_raw_data["definition"])
|
100
97
|
|
101
|
-
assert result.keys() == {"workflow_raw_data", "input_variables", "state_variables", "output_variables"}
|
102
|
-
assert workflow_raw_data.keys() == {"nodes", "edges", "display_data", "definition", "output_values"
|
98
|
+
assert result.keys() == {"workflow_raw_data", "input_variables", "state_variables", "output_variables", "triggers"}
|
99
|
+
assert workflow_raw_data.keys() == {"nodes", "edges", "display_data", "definition", "output_values"}
|
103
100
|
assert definition["name"] == "TestWorkflow"
|
104
101
|
|
105
102
|
|
@@ -3,7 +3,7 @@ import inspect
|
|
3
3
|
from io import StringIO
|
4
4
|
import sys
|
5
5
|
from uuid import UUID
|
6
|
-
from typing import TYPE_CHECKING, Any, Dict, List, cast
|
6
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast
|
7
7
|
|
8
8
|
from pydantic import BaseModel
|
9
9
|
|
@@ -248,13 +248,11 @@ def serialize_key(key: Any) -> str:
|
|
248
248
|
return str(key)
|
249
249
|
|
250
250
|
|
251
|
-
|
252
|
-
_UNDEFINED_SENTINEL: JsonObject = {"__undefined__": True}
|
253
|
-
|
254
|
-
|
255
|
-
def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContext", value: Any) -> JsonObject:
|
251
|
+
def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContext", value: Any) -> Optional[JsonObject]:
|
256
252
|
"""
|
257
|
-
Serialize a value to a JSON object.
|
253
|
+
Serialize a value to a JSON object. Returns `None` if the value resolves to `undefined`.
|
254
|
+
This is safe because all valid values are a JSON object, including the `None` constant:
|
255
|
+
> `{"type": "CONSTANT_VALUE", "value": {"type": "JSON", "value": None}}`
|
258
256
|
|
259
257
|
Args:
|
260
258
|
executable_id: node id or workflow id
|
@@ -265,7 +263,7 @@ def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContex
|
|
265
263
|
serialized value
|
266
264
|
"""
|
267
265
|
if value is undefined:
|
268
|
-
return
|
266
|
+
return None
|
269
267
|
|
270
268
|
if isinstance(value, ConstantValueReference):
|
271
269
|
return serialize_value(executable_id, display_context, value._value)
|
@@ -353,7 +351,7 @@ def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContex
|
|
353
351
|
serialized_items = []
|
354
352
|
for item in value:
|
355
353
|
serialized_item = serialize_value(executable_id, display_context, item)
|
356
|
-
if serialized_item
|
354
|
+
if serialized_item is not None:
|
357
355
|
serialized_items.append(serialized_item)
|
358
356
|
|
359
357
|
if all(isinstance(item, dict) and item["type"] == "CONSTANT_VALUE" for item in serialized_items):
|
@@ -389,7 +387,7 @@ def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContex
|
|
389
387
|
serialized_entries: List[Dict[str, Any]] = []
|
390
388
|
for key, val in value.items():
|
391
389
|
serialized_val = serialize_value(executable_id, display_context, val)
|
392
|
-
if serialized_val
|
390
|
+
if serialized_val is not None:
|
393
391
|
serialized_entries.append(
|
394
392
|
{
|
395
393
|
"id": str(uuid4_from_hash(f"{executable_id}|{key}")),
|
@@ -455,7 +453,9 @@ def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContex
|
|
455
453
|
if inputs:
|
456
454
|
serialized_inputs = {}
|
457
455
|
for param_name, input_ref in inputs.items():
|
458
|
-
|
456
|
+
serialized_input = serialize_value(executable_id, display_context, input_ref)
|
457
|
+
if serialized_input is not None:
|
458
|
+
serialized_inputs[param_name] = serialized_input
|
459
459
|
|
460
460
|
model_data = function_definition.model_dump()
|
461
461
|
model_data["inputs"] = serialized_inputs
|