vellum-ai 0.14.78__py3-none-any.whl → 0.14.80__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 +1 -1
- vellum/client/types/code_execution_package.py +2 -1
- vellum/workflows/types/utils.py +5 -2
- {vellum_ai-0.14.78.dist-info → vellum_ai-0.14.80.dist-info}/METADATA +1 -1
- {vellum_ai-0.14.78.dist-info → vellum_ai-0.14.80.dist-info}/RECORD +15 -15
- vellum_cli/__init__.py +2 -2
- vellum_cli/push.py +21 -6
- vellum_cli/tests/test_push.py +60 -0
- vellum_ee/workflows/display/nodes/vellum/base_adornment_node.py +3 -3
- vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py +8 -5
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +48 -15
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py +1 -1
- {vellum_ai-0.14.78.dist-info → vellum_ai-0.14.80.dist-info}/LICENSE +0 -0
- {vellum_ai-0.14.78.dist-info → vellum_ai-0.14.80.dist-info}/WHEEL +0 -0
- {vellum_ai-0.14.78.dist-info → vellum_ai-0.14.80.dist-info}/entry_points.txt +0 -0
@@ -18,7 +18,7 @@ class BaseClientWrapper:
|
|
18
18
|
headers: typing.Dict[str, str] = {
|
19
19
|
"X-Fern-Language": "Python",
|
20
20
|
"X-Fern-SDK-Name": "vellum-ai",
|
21
|
-
"X-Fern-SDK-Version": "0.14.
|
21
|
+
"X-Fern-SDK-Version": "0.14.80",
|
22
22
|
}
|
23
23
|
headers["X-API-KEY"] = self.api_key
|
24
24
|
return headers
|
@@ -1,14 +1,15 @@
|
|
1
1
|
# This file was auto-generated by Fern from our API Definition.
|
2
2
|
|
3
3
|
from ..core.pydantic_utilities import UniversalBaseModel
|
4
|
-
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
5
4
|
import typing
|
5
|
+
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
6
6
|
import pydantic
|
7
7
|
|
8
8
|
|
9
9
|
class CodeExecutionPackage(UniversalBaseModel):
|
10
10
|
version: str
|
11
11
|
name: str
|
12
|
+
repository: typing.Optional[str] = None
|
12
13
|
|
13
14
|
if IS_PYDANTIC_V2:
|
14
15
|
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
vellum/workflows/types/utils.py
CHANGED
@@ -49,9 +49,12 @@ def resolve_combined_types(
|
|
49
49
|
lhs_types = resolve_types(lhs)
|
50
50
|
rhs_types = resolve_types(rhs)
|
51
51
|
|
52
|
-
|
52
|
+
result_types: List[Union[Type[_LHS], Type[_RHS]]] = list(lhs_types)
|
53
|
+
for rhs_type in rhs_types:
|
54
|
+
if rhs_type not in result_types:
|
55
|
+
result_types.append(rhs_type)
|
53
56
|
|
54
|
-
return tuple(
|
57
|
+
return tuple(result_types)
|
55
58
|
|
56
59
|
|
57
60
|
def infer_types(object_: Type, attr_name: str, localns: Optional[Dict[str, Any]] = None) -> Tuple[Type, ...]:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
vellum_cli/CONTRIBUTING.md,sha256=FtDC7BGxSeMnwCXAUssFsAIElXtmJE-O5Z7BpolcgvI,2935
|
2
2
|
vellum_cli/README.md,sha256=2NudRoLzWxNKqnuVy1JuQ7DerIaxWGYkrH8kMd-asIE,90
|
3
|
-
vellum_cli/__init__.py,sha256=
|
3
|
+
vellum_cli/__init__.py,sha256=50dYVkBzGUS1i-UKf_9zv1JMif1lLClriNUSs-Z7i4E,12678
|
4
4
|
vellum_cli/aliased_group.py,sha256=ugW498j0yv4ALJ8vS9MsO7ctDW7Jlir9j6nE_uHAP8c,3363
|
5
5
|
vellum_cli/config.py,sha256=v5BmZ-t_v4Jmqd7KVuQMZF2pRI-rbMspSkVYXIRoTmI,9448
|
6
6
|
vellum_cli/image_push.py,sha256=rPeSfTlFpdTzwTdnXRL82OVd61qMoGFGLxnLjZLU98Q,10596
|
@@ -8,7 +8,7 @@ vellum_cli/init.py,sha256=WpnMXPItPmh0f0bBGIer3p-e5gu8DUGwSArT_FuoMEw,5093
|
|
8
8
|
vellum_cli/logger.py,sha256=dcM_OmgqXLo93vDYswO5ylyUQQcTfnA5GTd5tbIt3wM,1446
|
9
9
|
vellum_cli/ping.py,sha256=p_BCCRjgPhng6JktuECtkDQLbhopt6JpmrtGoLnLJT8,1161
|
10
10
|
vellum_cli/pull.py,sha256=udYyPlJ6VKDdh78rApNJOZgxHl82fcV6iGnRPSdX1LY,14750
|
11
|
-
vellum_cli/push.py,sha256=
|
11
|
+
vellum_cli/push.py,sha256=sUo0d7lm7saGxQciH-JW2FB_gWfP2gwoEHO1wGnNQR0,10933
|
12
12
|
vellum_cli/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
13
|
vellum_cli/tests/conftest.py,sha256=wx3PlJjVB0HRf5dr2b_idOIw27WPPl0J0FNbhIJJaVk,1689
|
14
14
|
vellum_cli/tests/test_config.py,sha256=uvKGDc8BoVyT9_H0Z-g8469zVxomn6Oi3Zj-vK7O_wU,2631
|
@@ -18,7 +18,7 @@ vellum_cli/tests/test_init.py,sha256=8UOc_ThfouR4ja5cCl_URuLk7ohr9JXfCnG4yka1OUQ
|
|
18
18
|
vellum_cli/tests/test_main.py,sha256=qDZG-aQauPwBwM6A2DIu1494n47v3pL28XakTbLGZ-k,272
|
19
19
|
vellum_cli/tests/test_ping.py,sha256=178EJHxPZtnnPMNXXynsQt8DIFhsrdc2bL17_YsG17M,2580
|
20
20
|
vellum_cli/tests/test_pull.py,sha256=hxMbW_j0weDDrkzVGpvLpFcwNQdn-fxTv4wBHeYizzc,49904
|
21
|
-
vellum_cli/tests/test_push.py,sha256=
|
21
|
+
vellum_cli/tests/test_push.py,sha256=wk9jQTV565TeukR0Vz-2AUQyJa3VlOJrmWxkSTX_Ptw,37860
|
22
22
|
vellum_ee/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
23
|
vellum_ee/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
24
|
vellum_ee/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -35,7 +35,7 @@ vellum_ee/workflows/display/nodes/types.py,sha256=St1BB6no528OyELGiyRabWao0GGw6m
|
|
35
35
|
vellum_ee/workflows/display/nodes/utils.py,sha256=sloya5TpXsnot1HURc9L51INwflRqUzHxRVnCS9Cd-4,973
|
36
36
|
vellum_ee/workflows/display/nodes/vellum/__init__.py,sha256=nUIgH2s0-7IbQRNrBhLPyRNe8YIrx3Yo9HeeW-aXXFk,1668
|
37
37
|
vellum_ee/workflows/display/nodes/vellum/api_node.py,sha256=5Uq8x08F64yrBcqbfsVeuoGnTa9eoOPumYzZZrDPmr0,8847
|
38
|
-
vellum_ee/workflows/display/nodes/vellum/base_adornment_node.py,sha256=
|
38
|
+
vellum_ee/workflows/display/nodes/vellum/base_adornment_node.py,sha256=FHhPoGmmny4Xcxi2pm12Sk3ZOREanWEVrOWcjRhncH4,6337
|
39
39
|
vellum_ee/workflows/display/nodes/vellum/code_execution_node.py,sha256=6lavdBw297GwAQqyxjnPUtx5pHv6k5V9Vkuq7s2D0TM,4508
|
40
40
|
vellum_ee/workflows/display/nodes/vellum/conditional_node.py,sha256=9GtbvSJUNF626tCYxnMxETVZm3Fq84vOZ3Nkdkl3n-M,11146
|
41
41
|
vellum_ee/workflows/display/nodes/vellum/error_node.py,sha256=YhMsi2TG1zSR8E7IpxzzSncOyVLcvqTuGa3mr4RqHd8,2364
|
@@ -62,7 +62,7 @@ vellum_ee/workflows/display/nodes/vellum/tests/test_retry_node.py,sha256=h93ysol
|
|
62
62
|
vellum_ee/workflows/display/nodes/vellum/tests/test_search_node.py,sha256=KvByxgbUkVyfPIVxTUBUk6a92JiJMi8eReZWxzfPExU,3864
|
63
63
|
vellum_ee/workflows/display/nodes/vellum/tests/test_subworkflow_deployment_node.py,sha256=BUzHJgjdWnPeZxjFjHfDBKnbFjYjnbXPjc-1hne1B2Y,3965
|
64
64
|
vellum_ee/workflows/display/nodes/vellum/tests/test_templating_node.py,sha256=LSk2gx9TpGXbAqKe8dggQW8yJZqj-Cf0EGJFeGGlEcw,3321
|
65
|
-
vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py,sha256=
|
65
|
+
vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py,sha256=YMoLNWknmSsFj7MtprenOYuXTX1VWUQ2bXZs_p76gBg,8163
|
66
66
|
vellum_ee/workflows/display/nodes/vellum/tests/test_try_node.py,sha256=Khjsb53PKpZuyhKoRMgKAL45eGp5hZqXvHmVeQWRw4w,2289
|
67
67
|
vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py,sha256=3LS1O4DGPWit05oj_ubeW8AlHGnoBxdUMferGQuAiZs,4851
|
68
68
|
vellum_ee/workflows/display/nodes/vellum/try_node.py,sha256=z9Omo676RRc7mQjLoL7hjiHhUj0OWVLhrrb97YTN4QA,4086
|
@@ -72,7 +72,7 @@ vellum_ee/workflows/display/tests/test_base_workflow_display.py,sha256=axUOLwpIh
|
|
72
72
|
vellum_ee/workflows/display/tests/workflow_serialization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
73
73
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
74
74
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py,sha256=XOQDDRiG46etxTC7-_RUEutoNumXc02fo7oho4GYM0c,1900
|
75
|
-
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py,sha256=
|
75
|
+
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py,sha256=aEmF6zpmmHdFgiG4V81EweOk5qO6cfukR782dYSE960,14060
|
76
76
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py,sha256=DFNp_iUxlyE-zCJBH9ab3e1jQEK-NSE9M2CQd4NCjY8,24853
|
77
77
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py,sha256=s6_mnk0pkztU59wYpSfOFpMhAJaRjmyfxM6WJGtnD4Y,6456
|
78
78
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py,sha256=PkSgghJDz0fpDB72HHPjLjo8LkZk-HpUkCQzRLX-iVw,40611
|
@@ -94,7 +94,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_
|
|
94
94
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py,sha256=V8b6gKghLlO7PJI8xeNdnfn8aII0W_IFQvSQBQM62UQ,7721
|
95
95
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py,sha256=hDWtKXmGI1CKhTwTNqpu_d5RkE5n7SolMLtgd87KqTI,3856
|
96
96
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py,sha256=6q-lTGMp5HbQba3NsHUFSit8_zEBxIVPGE8yCw4SVx0,25720
|
97
|
-
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py,sha256=
|
97
|
+
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py,sha256=aY76l9s_2nezx7hCfUZsPYFzvYMy-Rjd73G0DlL6s6A,9348
|
98
98
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_workflow_deployment_serialization.py,sha256=mova0sPD3evHiHIN1O0VynxlCp-uOcEIKve5Pd_oCDg,4069
|
99
99
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py,sha256=pLCyMScV88DTBXRH7jXaXOEA1GBq8NIipCUFwIAWnwI,2771
|
100
100
|
vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py,sha256=J4ouI8KxbMfxQP2Zq_9cWMGYgbjCWmKzjCJEtnSJb0I,5829
|
@@ -144,7 +144,7 @@ vellum/client/README.md,sha256=CuGUYnaE0Imt0KqQ4sIPaUghCjLHkF3DdEvZWu14-8s,4807
|
|
144
144
|
vellum/client/__init__.py,sha256=AYopGv2ZRVn3zsU8_km6KOvEHDbXiTPCVuYVI7bWvdA,120166
|
145
145
|
vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
|
146
146
|
vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
|
147
|
-
vellum/client/core/client_wrapper.py,sha256=
|
147
|
+
vellum/client/core/client_wrapper.py,sha256=28--LC1-hrUv3Yo5HQtt5VDbxX6iu7PRzaZPVD9oylU,1869
|
148
148
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
149
149
|
vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
|
150
150
|
vellum/client/core/http_client.py,sha256=Z77OIxIbL4OAB2IDqjRq_sYa5yNYAWfmdhdCSSvh6Y4,19552
|
@@ -265,7 +265,7 @@ vellum/client/types/code_execution_node_result_data.py,sha256=yLRzycagwxgwi-NGx8
|
|
265
265
|
vellum/client/types/code_execution_node_result_output.py,sha256=ZddnayoP01i5alC12OaoNdSgLoXr_Y4Nl343xGJvJeU,1069
|
266
266
|
vellum/client/types/code_execution_node_search_results_result.py,sha256=yPh94v7pgFL-4x1JPSnXXGihUi42i-OfOaNVHLN4jE8,740
|
267
267
|
vellum/client/types/code_execution_node_string_result.py,sha256=uH6KO57muMko4u_xISchhvP0E-VzJfhKD_rijXgisZ8,655
|
268
|
-
vellum/client/types/code_execution_package.py,sha256=
|
268
|
+
vellum/client/types/code_execution_package.py,sha256=ONMwxtIcz6zSZOd0wKaPC4Rz6S_scbYeiNZHuDMD8U4,624
|
269
269
|
vellum/client/types/code_execution_runtime.py,sha256=ucMXj7mUYl9-B_KentTfRuRIeDq33PV3OV_GWKiG-lo,181
|
270
270
|
vellum/client/types/code_executor_input.py,sha256=Dj6XRaIRHjbXDZ-wR_XusJkrxYD_lJ1-UZY0Ga4xeqI,694
|
271
271
|
vellum/client/types/code_executor_response.py,sha256=Xj2d86RMtodxHdfa4L0iaMkwyF0FgM7y6uBK-8WwOgE,673
|
@@ -1726,7 +1726,7 @@ vellum/workflows/types/stack.py,sha256=h7NE0vXR7l9DevFBIzIAk1Zh59K-kECQtDTKOUunw
|
|
1726
1726
|
vellum/workflows/types/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1727
1727
|
vellum/workflows/types/tests/test_definition.py,sha256=5wh_WEnE51epkoo-4PE-JbPlg8OGJUNlaBVWa9TcNSw,993
|
1728
1728
|
vellum/workflows/types/tests/test_utils.py,sha256=UnZog59tR577mVwqZRqqWn2fScoOU1H6up0EzS8zYhw,2536
|
1729
|
-
vellum/workflows/types/utils.py,sha256=
|
1729
|
+
vellum/workflows/types/utils.py,sha256=mTctHITBybpt4855x32oCKALBEcMNLn-9cCmfEKgJHQ,6498
|
1730
1730
|
vellum/workflows/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1731
1731
|
vellum/workflows/utils/functions.py,sha256=ZN0rrIBF4R_KNt1CbRPVNGR36xEMUa1T7FkgZioou-Y,7185
|
1732
1732
|
vellum/workflows/utils/names.py,sha256=QLUqfJ1tmSEeUwBKTTiv_Qk3QGbInC2RSmlXfGXc8Wo,380
|
@@ -1745,8 +1745,8 @@ vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnad
|
|
1745
1745
|
vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1746
1746
|
vellum/workflows/workflows/tests/test_base_workflow.py,sha256=fROqff6AZpCIzaSwOKSdtYy4XR0UZQ6ejxL3RJOSJVs,20447
|
1747
1747
|
vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
|
1748
|
-
vellum_ai-0.14.
|
1749
|
-
vellum_ai-0.14.
|
1750
|
-
vellum_ai-0.14.
|
1751
|
-
vellum_ai-0.14.
|
1752
|
-
vellum_ai-0.14.
|
1748
|
+
vellum_ai-0.14.80.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
1749
|
+
vellum_ai-0.14.80.dist-info/METADATA,sha256=AOpjIQ_DNiOeABYs3Y-0JAxvRnzf2jeZLJ0aQZMBcD0,5556
|
1750
|
+
vellum_ai-0.14.80.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
1751
|
+
vellum_ai-0.14.80.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
|
1752
|
+
vellum_ai-0.14.80.dist-info/RECORD,,
|
vellum_cli/__init__.py
CHANGED
@@ -67,7 +67,7 @@ with the provided module or be available for use. The Workflow Sandbox must also
|
|
67
67
|
@click.option("--deployment-label", type=str, help="Label to use for the Deployment")
|
68
68
|
@click.option("--deployment-name", type=str, help="Unique name for the Deployment")
|
69
69
|
@click.option("--deployment-description", type=str, help="Description for the Deployment")
|
70
|
-
@click.option("--release-tag",
|
70
|
+
@click.option("--release-tag", help="Release Tag for the Deployment", multiple=True)
|
71
71
|
@click.option(
|
72
72
|
"--dry-run",
|
73
73
|
is_flag=True,
|
@@ -117,7 +117,7 @@ def workflows_push(
|
|
117
117
|
@click.option("--deployment-label", type=str, help="Label to use for the Deployment")
|
118
118
|
@click.option("--deployment-name", type=str, help="Unique name for the Deployment")
|
119
119
|
@click.option("--deployment-description", type=str, help="Description for the Deployment")
|
120
|
-
@click.option("--release-tag",
|
120
|
+
@click.option("--release-tag", help="Release Tag for the Deployment", multiple=True)
|
121
121
|
@click.option(
|
122
122
|
"--dry-run",
|
123
123
|
is_flag=True,
|
vellum_cli/push.py
CHANGED
@@ -8,6 +8,7 @@ from uuid import UUID
|
|
8
8
|
from typing import List, Optional
|
9
9
|
|
10
10
|
from dotenv import load_dotenv
|
11
|
+
from pydantic import ValidationError
|
11
12
|
|
12
13
|
from vellum.client.core.api_error import ApiError
|
13
14
|
from vellum.resources.workflows.client import OMIT
|
@@ -129,12 +130,26 @@ def push_command(
|
|
129
130
|
workflow_config.deployments[0] if workflow_config.deployments else WorkflowDeploymentConfig()
|
130
131
|
)
|
131
132
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
133
|
+
try:
|
134
|
+
deployment_config = WorkflowPushDeploymentConfigRequest(
|
135
|
+
label=deployment_label or cli_deployment_config.label,
|
136
|
+
name=deployment_name or cli_deployment_config.name,
|
137
|
+
description=deployment_description or cli_deployment_config.description,
|
138
|
+
release_tags=release_tags or cli_deployment_config.release_tags,
|
139
|
+
)
|
140
|
+
except ValidationError as e:
|
141
|
+
for error in e.errors():
|
142
|
+
if "release_tags" in str(error.get("loc", [])):
|
143
|
+
handle_cli_error(
|
144
|
+
logger,
|
145
|
+
title="Invalid release tag format",
|
146
|
+
message="Release tags must be provided as separate arguments. "
|
147
|
+
"Use: --release-tag tag1 --release-tag tag2",
|
148
|
+
)
|
149
|
+
return
|
150
|
+
|
151
|
+
# Re-raise if it's not a release_tags validation error
|
152
|
+
raise e
|
138
153
|
|
139
154
|
# We should check with fern if we could auto-serialize typed fields for us
|
140
155
|
# https://app.shortcut.com/vellum/story/5568
|
vellum_cli/tests/test_push.py
CHANGED
@@ -979,3 +979,63 @@ def test_push__use_default_workspace_if_not_specified__multiple_workflows_config
|
|
979
979
|
config = configs[0]
|
980
980
|
assert config["workflow_sandbox_id"] == workflow_sandbox_id
|
981
981
|
assert config["workspace"] == "default"
|
982
|
+
|
983
|
+
|
984
|
+
def test_push__deploy_with_malformed_release_tags_shows_friendly_validation_error(mock_module, vellum_client):
|
985
|
+
# GIVEN a single workflow configured
|
986
|
+
temp_dir = mock_module.temp_dir
|
987
|
+
module = mock_module.module
|
988
|
+
|
989
|
+
# AND a workflow exists in the module successfully
|
990
|
+
_ensure_workflow_py(temp_dir, module)
|
991
|
+
|
992
|
+
# AND the push API call would return successfully
|
993
|
+
vellum_client.workflows.push.return_value = WorkflowPushResponse(
|
994
|
+
workflow_sandbox_id=str(uuid4()),
|
995
|
+
)
|
996
|
+
|
997
|
+
# WHEN calling `vellum workflows push` with --deploy and --release-tag
|
998
|
+
runner = CliRunner()
|
999
|
+
result = runner.invoke(cli_main, ["workflows", "push", module, "--deploy", "--release-tag", None]) # type: ignore
|
1000
|
+
|
1001
|
+
# THEN it should show the friendly error message instead of a raw Pydantic traceback
|
1002
|
+
assert "Invalid release tag format" in result.output
|
1003
|
+
assert "Release tags must be provided as separate arguments" in result.output
|
1004
|
+
assert "--release-tag tag1 --release-tag tag2" in result.output
|
1005
|
+
|
1006
|
+
|
1007
|
+
@pytest.mark.usefixtures("info_log_level")
|
1008
|
+
def test_push__deploy_with_release_tags_success(mock_module, vellum_client):
|
1009
|
+
# GIVEN a single workflow configured
|
1010
|
+
temp_dir = mock_module.temp_dir
|
1011
|
+
module = mock_module.module
|
1012
|
+
|
1013
|
+
# AND a workflow exists in the module successfully
|
1014
|
+
_ensure_workflow_py(temp_dir, module)
|
1015
|
+
|
1016
|
+
# AND the push API call returns successfully
|
1017
|
+
workflow_deployment_id = str(uuid4())
|
1018
|
+
vellum_client.workflows.push.return_value = WorkflowPushResponse(
|
1019
|
+
workflow_sandbox_id=str(uuid4()),
|
1020
|
+
workflow_deployment_id=workflow_deployment_id,
|
1021
|
+
)
|
1022
|
+
|
1023
|
+
# WHEN calling `vellum workflows push` with --deploy and --release-tag
|
1024
|
+
runner = CliRunner()
|
1025
|
+
result = runner.invoke(cli_main, ["workflows", "push", module, "--deploy", "--release-tag", "v1.0.0"])
|
1026
|
+
|
1027
|
+
# THEN it should succeed
|
1028
|
+
assert result.exit_code == 0, result.output
|
1029
|
+
|
1030
|
+
# AND we should have called the push API with the correct deployment config
|
1031
|
+
vellum_client.workflows.push.assert_called_once()
|
1032
|
+
call_args = vellum_client.workflows.push.call_args.kwargs
|
1033
|
+
|
1034
|
+
# AND the deployment_config should contain the release tags
|
1035
|
+
deployment_config_str = call_args["deployment_config"]
|
1036
|
+
deployment_config = json.loads(deployment_config_str)
|
1037
|
+
assert deployment_config["release_tags"] == ["v1.0.0"]
|
1038
|
+
|
1039
|
+
# AND should show success message
|
1040
|
+
assert "Successfully pushed" in result.output
|
1041
|
+
assert "Updated vellum.lock.json file." in result.output
|
@@ -6,7 +6,7 @@ from typing import Any, Callable, Dict, Generic, Optional, Type, TypeVar, cast
|
|
6
6
|
from vellum.workflows.nodes.bases.base import BaseNode
|
7
7
|
from vellum.workflows.nodes.bases.base_adornment_node import BaseAdornmentNode
|
8
8
|
from vellum.workflows.nodes.utils import get_wrapped_node
|
9
|
-
from vellum.workflows.types.core import
|
9
|
+
from vellum.workflows.types.core import JsonObject
|
10
10
|
from vellum.workflows.types.utils import get_original_base
|
11
11
|
from vellum.workflows.utils.uuids import uuid4_from_hash
|
12
12
|
from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
|
@@ -94,8 +94,8 @@ class BaseAdornmentNodeDisplay(BaseNodeDisplay[_BaseAdornmentNodeType], Generic[
|
|
94
94
|
additional_kwargs = get_additional_kwargs(wrapped_node_display.node_id) if get_additional_kwargs else {}
|
95
95
|
serialized_wrapped_node = wrapped_node_display.serialize(display_context, **kwargs, **additional_kwargs)
|
96
96
|
|
97
|
-
adornments = cast(
|
98
|
-
serialized_wrapped_node["adornments"] =
|
97
|
+
adornments = cast(list, serialized_wrapped_node.get("adornments")) or []
|
98
|
+
serialized_wrapped_node["adornments"] = [adornment] + adornments if adornment else adornments
|
99
99
|
|
100
100
|
return serialized_wrapped_node
|
101
101
|
|
@@ -139,8 +139,8 @@ def test_serialize_node__function_configs():
|
|
139
139
|
"foo": {
|
140
140
|
"runtime": "PYTHON_3_11_6",
|
141
141
|
"packages": [
|
142
|
-
CodeExecutionPackage(name="first_package", version="1.0.0"),
|
143
|
-
CodeExecutionPackage(name="second_package", version="2.0.0"),
|
142
|
+
CodeExecutionPackage(name="first_package", version="1.0.0", repository="test-repo"),
|
143
|
+
CodeExecutionPackage(name="second_package", version="2.0.0", repository="test-repo"),
|
144
144
|
],
|
145
145
|
},
|
146
146
|
"bar": {
|
@@ -179,11 +179,14 @@ def test_serialize_node__function_configs():
|
|
179
179
|
"foo": {
|
180
180
|
"runtime": "PYTHON_3_11_6",
|
181
181
|
"packages": [
|
182
|
-
{"version": "1.0.0", "name": "first_package"},
|
183
|
-
{"version": "2.0.0", "name": "second_package"},
|
182
|
+
{"version": "1.0.0", "name": "first_package", "repository": "test-repo"},
|
183
|
+
{"version": "2.0.0", "name": "second_package", "repository": "test-repo"},
|
184
184
|
],
|
185
185
|
},
|
186
|
-
"bar": {
|
186
|
+
"bar": {
|
187
|
+
"runtime": "PYTHON_3_11_6",
|
188
|
+
"packages": [{"version": "3.0.0", "name": "third_package", "repository": None}],
|
189
|
+
},
|
187
190
|
},
|
188
191
|
},
|
189
192
|
},
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from uuid import uuid4
|
2
|
+
from typing import Any, Dict, List, cast
|
2
3
|
|
3
4
|
from deepdiff import DeepDiff
|
4
5
|
|
@@ -269,6 +270,21 @@ def test_serialize_node__stacked():
|
|
269
270
|
},
|
270
271
|
"ports": [{"id": "408cd5fb-3a3e-4eb2-9889-61111bd6a129", "name": "default", "type": "DEFAULT"}],
|
271
272
|
"adornments": [
|
273
|
+
{
|
274
|
+
"id": "3344083c-a32c-4a32-920b-0fb5093448fa",
|
275
|
+
"label": "TryNode",
|
276
|
+
"base": {
|
277
|
+
"name": "TryNode",
|
278
|
+
"module": ["vellum", "workflows", "nodes", "core", "try_node", "node"],
|
279
|
+
},
|
280
|
+
"attributes": [
|
281
|
+
{
|
282
|
+
"id": "ab2fbab0-e2a0-419b-b1ef-ce11ecf11e90",
|
283
|
+
"name": "on_error_code",
|
284
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "JSON", "value": None}},
|
285
|
+
}
|
286
|
+
],
|
287
|
+
},
|
272
288
|
{
|
273
289
|
"id": "5be7d260-74f7-4734-b31b-a46a94539586",
|
274
290
|
"label": "RetryNode",
|
@@ -299,24 +315,41 @@ def test_serialize_node__stacked():
|
|
299
315
|
},
|
300
316
|
],
|
301
317
|
},
|
302
|
-
{
|
303
|
-
"id": "3344083c-a32c-4a32-920b-0fb5093448fa",
|
304
|
-
"label": "TryNode",
|
305
|
-
"base": {
|
306
|
-
"name": "TryNode",
|
307
|
-
"module": ["vellum", "workflows", "nodes", "core", "try_node", "node"],
|
308
|
-
},
|
309
|
-
"attributes": [
|
310
|
-
{
|
311
|
-
"id": "ab2fbab0-e2a0-419b-b1ef-ce11ecf11e90",
|
312
|
-
"name": "on_error_code",
|
313
|
-
"value": {"type": "CONSTANT_VALUE", "value": {"type": "JSON", "value": None}},
|
314
|
-
}
|
315
|
-
],
|
316
|
-
},
|
317
318
|
],
|
318
319
|
"attributes": [],
|
319
320
|
"outputs": [],
|
320
321
|
},
|
321
322
|
inner_stacked_generic_node,
|
322
323
|
)
|
324
|
+
|
325
|
+
|
326
|
+
def test_serialize_node__adornment_order_matches_decorator_order():
|
327
|
+
"""
|
328
|
+
Tests that adornments are serialized in the same order as decorators are applied.
|
329
|
+
"""
|
330
|
+
|
331
|
+
@TryNode.wrap()
|
332
|
+
@RetryNode.wrap(max_attempts=3)
|
333
|
+
class MyNode(BaseNode):
|
334
|
+
pass
|
335
|
+
|
336
|
+
# AND a workflow that uses the decorated node
|
337
|
+
class MyWorkflow(BaseWorkflow):
|
338
|
+
graph = MyNode
|
339
|
+
|
340
|
+
# WHEN we serialize the workflow
|
341
|
+
workflow_display = get_workflow_display(workflow_class=MyWorkflow)
|
342
|
+
exec_config = cast(Dict[str, Any], workflow_display.serialize())
|
343
|
+
|
344
|
+
# THEN the workflow should serialize successfully
|
345
|
+
assert isinstance(exec_config["workflow_raw_data"], dict)
|
346
|
+
assert isinstance(exec_config["workflow_raw_data"]["nodes"], list)
|
347
|
+
|
348
|
+
# AND we should find our decorated node
|
349
|
+
nodes = cast(List[Dict[str, Any]], exec_config["workflow_raw_data"]["nodes"])
|
350
|
+
my_node = [node for node in nodes if isinstance(node, dict) and node["type"] == "GENERIC"][0]
|
351
|
+
|
352
|
+
adornments = cast(List[Dict[str, Any]], my_node["adornments"])
|
353
|
+
assert len(adornments) == 2
|
354
|
+
assert adornments[0]["label"] == "TryNode"
|
355
|
+
assert adornments[1]["label"] == "RetryNode"
|
@@ -162,7 +162,7 @@ def test_serialize_workflow():
|
|
162
162
|
"value": {
|
163
163
|
"get_current_weather": {
|
164
164
|
"runtime": "PYTHON_3_11_6",
|
165
|
-
"packages": [{"version": "2.26.0", "name": "requests"}],
|
165
|
+
"packages": [{"version": "2.26.0", "name": "requests", "repository": None}],
|
166
166
|
}
|
167
167
|
},
|
168
168
|
},
|
File without changes
|
File without changes
|
File without changes
|