vellum-ai 0.14.18__py3-none-any.whl → 0.14.19__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 CHANGED
@@ -229,6 +229,7 @@ from .types import (
229
229
  NodeInputCompiledJsonValue,
230
230
  NodeInputCompiledNumberValue,
231
231
  NodeInputCompiledSearchResultsValue,
232
+ NodeInputCompiledSecretValue,
232
233
  NodeInputCompiledStringValue,
233
234
  NodeInputVariableCompiledValue,
234
235
  NodeOutputCompiledArrayValue,
@@ -777,6 +778,7 @@ __all__ = [
777
778
  "NodeInputCompiledJsonValue",
778
779
  "NodeInputCompiledNumberValue",
779
780
  "NodeInputCompiledSearchResultsValue",
781
+ "NodeInputCompiledSecretValue",
780
782
  "NodeInputCompiledStringValue",
781
783
  "NodeInputVariableCompiledValue",
782
784
  "NodeOutputCompiledArrayValue",
@@ -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.18",
21
+ "X-Fern-SDK-Version": "0.14.19",
22
22
  }
23
23
  headers["X_API_KEY"] = self.api_key
24
24
  return headers
@@ -237,6 +237,7 @@ from .node_input_compiled_function_call_value import NodeInputCompiledFunctionCa
237
237
  from .node_input_compiled_json_value import NodeInputCompiledJsonValue
238
238
  from .node_input_compiled_number_value import NodeInputCompiledNumberValue
239
239
  from .node_input_compiled_search_results_value import NodeInputCompiledSearchResultsValue
240
+ from .node_input_compiled_secret_value import NodeInputCompiledSecretValue
240
241
  from .node_input_compiled_string_value import NodeInputCompiledStringValue
241
242
  from .node_input_variable_compiled_value import NodeInputVariableCompiledValue
242
243
  from .node_output_compiled_array_value import NodeOutputCompiledArrayValue
@@ -759,6 +760,7 @@ __all__ = [
759
760
  "NodeInputCompiledJsonValue",
760
761
  "NodeInputCompiledNumberValue",
761
762
  "NodeInputCompiledSearchResultsValue",
763
+ "NodeInputCompiledSecretValue",
762
764
  "NodeInputCompiledStringValue",
763
765
  "NodeInputVariableCompiledValue",
764
766
  "NodeOutputCompiledArrayValue",
@@ -0,0 +1,23 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.pydantic_utilities import UniversalBaseModel
4
+ import typing
5
+ from .vellum_secret import VellumSecret
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
+ import pydantic
8
+
9
+
10
+ class NodeInputCompiledSecretValue(UniversalBaseModel):
11
+ node_input_id: str
12
+ key: str
13
+ type: typing.Literal["SECRET"] = "SECRET"
14
+ value: VellumSecret
15
+
16
+ if IS_PYDANTIC_V2:
17
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
18
+ else:
19
+
20
+ class Config:
21
+ frozen = True
22
+ smart_union = True
23
+ extra = pydantic.Extra.allow
@@ -9,6 +9,7 @@ from .node_input_compiled_search_results_value import NodeInputCompiledSearchRes
9
9
  from .node_input_compiled_error_value import NodeInputCompiledErrorValue
10
10
  from .node_input_compiled_array_value import NodeInputCompiledArrayValue
11
11
  from .node_input_compiled_function_call_value import NodeInputCompiledFunctionCallValue
12
+ from .node_input_compiled_secret_value import NodeInputCompiledSecretValue
12
13
 
13
14
  NodeInputVariableCompiledValue = typing.Union[
14
15
  NodeInputCompiledStringValue,
@@ -19,4 +20,5 @@ NodeInputVariableCompiledValue = typing.Union[
19
20
  NodeInputCompiledErrorValue,
20
21
  NodeInputCompiledArrayValue,
21
22
  NodeInputCompiledFunctionCallValue,
23
+ NodeInputCompiledSecretValue,
22
24
  ]
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.node_input_compiled_secret_value import *
@@ -4,7 +4,7 @@ from vellum.workflows.constants import undefined
4
4
  from vellum.workflows.context import execution_context, get_parent_context
5
5
  from vellum.workflows.errors.types import WorkflowErrorCode
6
6
  from vellum.workflows.events.workflow import is_workflow_event
7
- from vellum.workflows.exceptions import NodeException
7
+ from vellum.workflows.exceptions import NodeException, WorkflowInitializationException
8
8
  from vellum.workflows.inputs.base import BaseInputs
9
9
  from vellum.workflows.nodes.bases.base import BaseNode, BaseNodeMeta
10
10
  from vellum.workflows.outputs.base import BaseOutput, BaseOutputs
@@ -119,19 +119,21 @@ class InlineSubworkflowNode(
119
119
 
120
120
  def _compile_subworkflow_inputs(self) -> InputsType:
121
121
  inputs_class = self.subworkflow.get_inputs_class()
122
- if self.subworkflow_inputs is undefined:
123
- inputs_dict = {}
124
- for descriptor in inputs_class:
125
- if hasattr(self, descriptor.name):
126
- inputs_dict[descriptor.name] = getattr(self, descriptor.name)
127
-
128
- return inputs_class(**inputs_dict)
129
- elif isinstance(self.subworkflow_inputs, dict):
130
- return inputs_class(**self.subworkflow_inputs)
131
- elif isinstance(self.subworkflow_inputs, inputs_class):
132
- return self.subworkflow_inputs
133
- else:
134
- raise ValueError(f"Invalid subworkflow inputs type: {type(self.subworkflow_inputs)}")
122
+ try:
123
+ if self.subworkflow_inputs is undefined:
124
+ inputs_dict = {}
125
+ for descriptor in inputs_class:
126
+ if hasattr(self, descriptor.name):
127
+ inputs_dict[descriptor.name] = getattr(self, descriptor.name)
128
+ return inputs_class(**inputs_dict)
129
+ elif isinstance(self.subworkflow_inputs, dict):
130
+ return inputs_class(**self.subworkflow_inputs)
131
+ elif isinstance(self.subworkflow_inputs, inputs_class):
132
+ return self.subworkflow_inputs
133
+ else:
134
+ raise ValueError(f"Invalid subworkflow inputs type: {type(self.subworkflow_inputs)}")
135
+ except WorkflowInitializationException as e:
136
+ raise NodeException(message=str(e), code=e.code)
135
137
 
136
138
  @classmethod
137
139
  def __annotate_outputs_class__(cls, outputs_class: Type[BaseOutputs], reference: OutputReference) -> None:
@@ -1,5 +1,7 @@
1
1
  import pytest
2
2
 
3
+ from vellum.workflows.errors.types import WorkflowErrorCode
4
+ from vellum.workflows.exceptions import NodeException
3
5
  from vellum.workflows.inputs.base import BaseInputs
4
6
  from vellum.workflows.nodes.bases.base import BaseNode
5
7
  from vellum.workflows.nodes.core.inline_subworkflow_node.node import InlineSubworkflowNode
@@ -87,3 +89,30 @@ def test_inline_subworkflow_node__nested_try():
87
89
  # THEN we only have the outer node's outputs
88
90
  valid_events = [e for e in events if e.name == "bar"]
89
91
  assert len(valid_events) == len(events)
92
+
93
+
94
+ def test_inline_subworkflow_node__base_inputs_validation():
95
+ """Test that InlineSubworkflowNode properly validates required inputs"""
96
+
97
+ # GIVEN a real subworkflow class with a required input
98
+ class SubworkflowInputs(BaseInputs):
99
+ required_input: str # This is a required field without a default
100
+
101
+ class TestSubworkflow(BaseWorkflow[SubworkflowInputs, BaseState]):
102
+ pass
103
+
104
+ # AND a node that uses this subworkflow
105
+ class TestNode(InlineSubworkflowNode):
106
+ subworkflow = TestSubworkflow
107
+ subworkflow_inputs = {"required_input": None}
108
+
109
+ # WHEN we try to run the node
110
+ node = TestNode()
111
+
112
+ # THEN it should raise a NodeException
113
+ with pytest.raises(NodeException) as e:
114
+ list(node.run())
115
+
116
+ # AND the error message should indicate the missing required input
117
+ assert e.value.code == WorkflowErrorCode.INVALID_INPUTS
118
+ assert "Required input variables required_input should have defined value" == str(e.value)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.14.18
3
+ Version: 0.14.19
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -24,7 +24,7 @@ vellum_ee/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
24
24
  vellum_ee/workflows/display/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  vellum_ee/workflows/display/base.py,sha256=ak29FIsawhaFa9_paZUHThlZRFJ1xB486JWKuSt1PYY,1965
26
26
  vellum_ee/workflows/display/nodes/__init__.py,sha256=436iSAh_Ex5tC68oEYvNgPu05ZVIAVXnS4PKGrQeZ0Y,321
27
- vellum_ee/workflows/display/nodes/base_node_display.py,sha256=H7LJGtGWFkypyNhIrIhHoGYXS0hRYcP7aoYHlM90f_U,17395
27
+ vellum_ee/workflows/display/nodes/base_node_display.py,sha256=qBF1uZybN8dHzyMRvjqf3rWlAl0fdODV5h6WblhGJP8,17703
28
28
  vellum_ee/workflows/display/nodes/base_node_vellum_display.py,sha256=ZLKQ8Xa3h9nGkj4t4V_7OeU7CBFWY3gXB9CkaCLOhEk,2699
29
29
  vellum_ee/workflows/display/nodes/get_node_display_class.py,sha256=LhV2wSo07iOTUj1clKwH2zzCzKdLiW2gk22R3Qco81E,2196
30
30
  vellum_ee/workflows/display/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -34,7 +34,7 @@ vellum_ee/workflows/display/nodes/utils.py,sha256=sloya5TpXsnot1HURc9L51INwflRqU
34
34
  vellum_ee/workflows/display/nodes/vellum/__init__.py,sha256=nUIgH2s0-7IbQRNrBhLPyRNe8YIrx3Yo9HeeW-aXXFk,1668
35
35
  vellum_ee/workflows/display/nodes/vellum/api_node.py,sha256=hoV-cUtS6H9kmRQXHd2py95GRWI_dAnnaPwvlNBkDOQ,8571
36
36
  vellum_ee/workflows/display/nodes/vellum/base_adornment_node.py,sha256=oJAQrAm5iFQq0_fX94sMbS3RQEK1M1VsoUck4vsPs9A,5820
37
- vellum_ee/workflows/display/nodes/vellum/code_execution_node.py,sha256=z00Z3L0d4PsUQo4S8FRDTtOFLtjdi17TJbatNVF4nM8,4288
37
+ vellum_ee/workflows/display/nodes/vellum/code_execution_node.py,sha256=uIEpWxO8SYA_sb-EK_4wdyYEwGQOnykAOExFRkZcFaE,4241
38
38
  vellum_ee/workflows/display/nodes/vellum/conditional_node.py,sha256=ybLIa4uclqVIy3VAQvI1ivg2tnK5Ug_1R5a69DFqL7E,11104
39
39
  vellum_ee/workflows/display/nodes/vellum/error_node.py,sha256=I1Jkp2htRINJATtv1e-zs9BrReFX842djpiVgBPHDYg,2186
40
40
  vellum_ee/workflows/display/nodes/vellum/final_output_node.py,sha256=p-PvlnxpBQ7IKskZi2A19jKAtKnSxJ8LPbGMA83VkFk,2805
@@ -64,7 +64,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/__init__.py,sha256=47DE
64
64
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
65
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py,sha256=A1-tIpC5KIKG9JA_rkd1nLS8zUG3Kb4QiVdvb3boFxE,2509
66
66
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py,sha256=2ZDTmpiU2CcZe4ukxoQ79SJx8V8kDRQHgUxP5Vtesus,15605
67
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py,sha256=lScpUiz8fvUmJK18Cpygs9xQrfHQlkSIlmxapGYTS0g,18770
67
+ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py,sha256=oEtjTovI6-T_OGND7UBDnBig0kjVm0bPwWMUbRCV1OU,19781
68
68
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py,sha256=KgxSN8L5AWPL8EpQfSZiTqK428nAIElcWrV-sR17528,6456
69
69
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py,sha256=yS8GpjbH0objjcNYK73j8rDHbhqinIbG7CcoNjnolBg,40611
70
70
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py,sha256=_-ADur28OkVy4YEgMHkkVYqMbS1j3GcOtX9MTYmmvf0,4632
@@ -120,12 +120,12 @@ vellum_ee/workflows/tests/local_workflow/workflow.py,sha256=A4qOzOPNwePYxWbcAgIP
120
120
  vellum_ee/workflows/tests/test_display_meta.py,sha256=C25dErwghPNXio49pvSRxyOuc96srH6eYEwTAWdE2zY,2258
121
121
  vellum_ee/workflows/tests/test_server.py,sha256=M6vvQ2hjIpDWtQdDM9EPbMvUrZ93niAuYnxMNJWOjPA,511
122
122
  vellum_ee/workflows/tests/test_virtual_files.py,sha256=TJEcMR0v2S8CkloXNmCHA0QW0K6pYNGaIjraJz7sFvY,2762
123
- vellum/__init__.py,sha256=Vh9jxpBVXB2fTCyoUMlLdGL1Ujf0zNNNvqhNu5II8KI,36466
123
+ vellum/__init__.py,sha256=qJRjommzKdcsfZUNkqN2k1BuOwVVSuX4Nuv9ITCz1AM,36536
124
124
  vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
125
125
  vellum/client/__init__.py,sha256=tKtdM1_GqmGq1gpi9ydWD_T-MM7fPn8QdHh8ww19cNI,117564
126
126
  vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
127
127
  vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
128
- vellum/client/core/client_wrapper.py,sha256=uLm2G6JmYjhKSyX55XTjjoXumxodrRRDWg6-C5GmXLI,1869
128
+ vellum/client/core/client_wrapper.py,sha256=ZLOoZbFrHfMWTwl3j2UlsGsUsTrHJM0L9ZyltUPXo1g,1869
129
129
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
130
130
  vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
131
131
  vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
@@ -190,7 +190,7 @@ vellum/client/resources/workspace_secrets/__init__.py,sha256=FTtvy8EDg9nNNg9WCat
190
190
  vellum/client/resources/workspace_secrets/client.py,sha256=h7UzXLyTttPq1t-JZGMg1BWxypxJvBGUdqg7KGT7MK4,8027
191
191
  vellum/client/resources/workspaces/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
192
192
  vellum/client/resources/workspaces/client.py,sha256=RthwzN1o-Jxwg5yyNNodavFyNUSxfLoTv26w3mRR5g8,3595
193
- vellum/client/types/__init__.py,sha256=D6j2QfxOV3WULH0inmz9q-gdOQcytrr6_R8WYaC5ZZk,54894
193
+ vellum/client/types/__init__.py,sha256=H2K-qwJM2gg5ZOMIXT56gwK1Vr0iV45hb11ON5z_dL4,55005
194
194
  vellum/client/types/ad_hoc_execute_prompt_event.py,sha256=bCjujA2XsOgyF3bRZbcEqV2rOIymRgsLoIRtZpB14xg,607
195
195
  vellum/client/types/ad_hoc_expand_meta.py,sha256=1gv-NCsy_6xBYupLvZH979yf2VMdxAU-l0y0ynMKZaw,1331
196
196
  vellum/client/types/ad_hoc_fulfilled_prompt_execution_meta.py,sha256=Bfvf1d_dkmshxRACVM5vcxbH_7AQY23RmrrnPc0ytYY,939
@@ -416,8 +416,9 @@ vellum/client/types/node_input_compiled_function_call_value.py,sha256=Q9vrORvrPD
416
416
  vellum/client/types/node_input_compiled_json_value.py,sha256=ketb8FNY9DQjAxgJd4SPDE6ErHJYY0NEkW0-STapBkw,679
417
417
  vellum/client/types/node_input_compiled_number_value.py,sha256=Olc4UpYsm-v7ZhlTVXsp7JVQE0ytLsBSd9HolCYWmZ4,680
418
418
  vellum/client/types/node_input_compiled_search_results_value.py,sha256=A2SnHYZAt2_VsQDXL4B2CF3KYgDJeUAQ5L0RbI8flH0,763
419
+ vellum/client/types/node_input_compiled_secret_value.py,sha256=yY-OBwHZ4k9uCf_1dQpV6wFZTW_tcC7RSq41Xj-ToPU,703
419
420
  vellum/client/types/node_input_compiled_string_value.py,sha256=V4HKhHW6B2iUvYqYbuwcOHTxiui3nfOe0DKOiTXshJQ,678
420
- vellum/client/types/node_input_variable_compiled_value.py,sha256=ahG5KdRDQ97w3Ljhfz9EssY0FD1DKeE4C5y393QOS78,1046
421
+ vellum/client/types/node_input_variable_compiled_value.py,sha256=h3AovF98U2Wkuo35DAjD6GlUSBo8KbdNt2hyMBDEJuM,1155
421
422
  vellum/client/types/node_output_compiled_array_value.py,sha256=-lUee9E-IrlndzNS-tzfAQrEOZv-ZcgAmm06_kcqOr8,1176
422
423
  vellum/client/types/node_output_compiled_chat_history_value.py,sha256=rAAnJ2PcXGxKusMpq2NEhJdBSRrPB9da5uN19x92Wu4,962
423
424
  vellum/client/types/node_output_compiled_error_value.py,sha256=dkgT_h463S8AF3QHVZdvy9HGF3A2LhxuNnAQouAYQlE,922
@@ -1008,6 +1009,7 @@ vellum/types/node_input_compiled_function_call_value.py,sha256=KAQGyfyBZCsMZUxRI
1008
1009
  vellum/types/node_input_compiled_json_value.py,sha256=RZ0qcWJ8XgTxQuOxTNaJmzObEaTDE66797ySeKrr6Hg,168
1009
1010
  vellum/types/node_input_compiled_number_value.py,sha256=H-92wifgPNQxIWzxBBpPO6x8i_HRfHaJWn5xPDDB_qk,170
1010
1011
  vellum/types/node_input_compiled_search_results_value.py,sha256=5pqbGkgX_r4fKiMlnPcovPzHhkl9yhenoPx_zz1rizc,178
1012
+ vellum/types/node_input_compiled_secret_value.py,sha256=FGS_HTzO41MQ0g-RH0hp61ePLDIoClHZ5yQgBrw5QrM,170
1011
1013
  vellum/types/node_input_compiled_string_value.py,sha256=lZfKVBkffPKbONZjljxKMrcBUXvSwBpKb2YSq9TiApo,170
1012
1014
  vellum/types/node_input_variable_compiled_value.py,sha256=DHrIaSM4AOAzy5JCjSNoQnlr_yvarntDWjpVgo3Ni7w,172
1013
1015
  vellum/types/node_output_compiled_array_value.py,sha256=6sodx6QYM2IyVtPiYsAm6g4vQ4U_tqBXcQ6_OeBkmYQ,170
@@ -1374,9 +1376,9 @@ vellum/workflows/nodes/core/__init__.py,sha256=5zDMCmyt1v0HTJzlUBwq3U9L825yZGZhT
1374
1376
  vellum/workflows/nodes/core/error_node/__init__.py,sha256=g7RRnlHhqu4qByfLjBwCunmgGA8dI5gNsjS3h6TwlSI,60
1375
1377
  vellum/workflows/nodes/core/error_node/node.py,sha256=MFHU5vITYSK-L9CuMZ49In2ZeNLWnhZD0f8r5dWvb5Y,1270
1376
1378
  vellum/workflows/nodes/core/inline_subworkflow_node/__init__.py,sha256=nKNEH1QTl-1PcvmYoqSWEl0-t6gAur8GLTXHzklRQfM,84
1377
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py,sha256=B1ant-Pwg1AGFs5BYXynHf2i4rAen1bkr7nbLmiVwHo,6175
1379
+ vellum/workflows/nodes/core/inline_subworkflow_node/node.py,sha256=1RZ9x69qwziPupR5pkUQVTQnEaF4ieaJ8Uvx2gSbiow,6382
1378
1380
  vellum/workflows/nodes/core/inline_subworkflow_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1379
- vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py,sha256=6AG-oTyJaw5a1KWGQFNZaKl6_Pu_fW3nI_WA3XNRFWY,2439
1381
+ vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py,sha256=BLmwLeWxgn6RgRKL8gi8bvV2ZfWnCTsqZDykTgJOjXg,3529
1380
1382
  vellum/workflows/nodes/core/map_node/__init__.py,sha256=MXpZYmGfhsMJHqqlpd64WiJRtbAtAMQz-_3fCU_cLV0,56
1381
1383
  vellum/workflows/nodes/core/map_node/node.py,sha256=dY27Xm11LHsqD7hnZnVYYDIazZ-XfL4_zatvWKTi6CU,9243
1382
1384
  vellum/workflows/nodes/core/map_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1518,8 +1520,8 @@ vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnad
1518
1520
  vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1519
1521
  vellum/workflows/workflows/tests/test_base_workflow.py,sha256=NRteiICyJvDM5zrtUfq2fZoXcGQVaWC9xmNlLLVW0cU,7979
1520
1522
  vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
1521
- vellum_ai-0.14.18.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1522
- vellum_ai-0.14.18.dist-info/METADATA,sha256=jfwatBq_nGnqnh-_g3EkOaoxQtBIU5O4Gn7n-v3F_do,5408
1523
- vellum_ai-0.14.18.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1524
- vellum_ai-0.14.18.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1525
- vellum_ai-0.14.18.dist-info/RECORD,,
1523
+ vellum_ai-0.14.19.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1524
+ vellum_ai-0.14.19.dist-info/METADATA,sha256=_Ot_Bgq5LluSkVWep3mE9BIZn1f5WMD1VbDLEhGECw0,5408
1525
+ vellum_ai-0.14.19.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1526
+ vellum_ai-0.14.19.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1527
+ vellum_ai-0.14.19.dist-info/RECORD,,
@@ -129,13 +129,16 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
129
129
  continue
130
130
 
131
131
  id = str(uuid4_from_hash(f"{node_id}|{attribute.name}"))
132
- attributes.append(
133
- {
134
- "id": id,
135
- "name": attribute.name,
136
- "value": self.serialize_value(display_context, cast(BaseDescriptor, attribute.instance)),
137
- }
138
- )
132
+ try:
133
+ attributes.append(
134
+ {
135
+ "id": id,
136
+ "name": attribute.name,
137
+ "value": self.serialize_value(display_context, attribute.instance),
138
+ }
139
+ )
140
+ except ValueError as e:
141
+ raise ValueError(f"Failed to serialize attribute '{attribute.name}': {e}")
139
142
 
140
143
  adornments = kwargs.get("adornments", None)
141
144
  wrapped_node = get_wrapped_node(node)
@@ -369,7 +372,7 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
369
372
  "rhs": rhs,
370
373
  }
371
374
 
372
- def serialize_value(self, display_context: "WorkflowDisplayContext", value: BaseDescriptor) -> JsonObject:
375
+ def serialize_value(self, display_context: "WorkflowDisplayContext", value: Any) -> JsonObject:
373
376
  if isinstance(value, ConstantValueReference):
374
377
  return self.serialize_value(display_context, value._value)
375
378
 
@@ -415,6 +418,9 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
415
418
  "node_id": str(node_class_display.node_id),
416
419
  }
417
420
 
421
+ if isinstance(value, dict) and any(isinstance(v, BaseDescriptor) for v in value.values()):
422
+ raise ValueError("Nested references are not supported.")
423
+
418
424
  if not isinstance(value, BaseDescriptor):
419
425
  vellum_value = primitive_to_vellum_value(value)
420
426
  return {
@@ -15,9 +15,6 @@ _CodeExecutionNodeType = TypeVar("_CodeExecutionNodeType", bound=CodeExecutionNo
15
15
 
16
16
 
17
17
  class BaseCodeExecutionNodeDisplay(BaseNodeVellumDisplay[_CodeExecutionNodeType], Generic[_CodeExecutionNodeType]):
18
- code_input_id: ClassVar[Optional[UUID]] = None
19
- runtime_input_id: ClassVar[Optional[UUID]] = None
20
-
21
18
  output_id: ClassVar[Optional[UUID]] = None
22
19
  log_output_id: ClassVar[Optional[UUID]] = None
23
20
 
@@ -52,19 +49,22 @@ class BaseCodeExecutionNodeDisplay(BaseNodeVellumDisplay[_CodeExecutionNodeType]
52
49
  for variable_name, variable_value in code_inputs.items()
53
50
  ]
54
51
 
52
+ code_input_id = self.node_input_ids_by_name.get(CodeExecutionNode.code.name)
55
53
  code_node_input = create_node_input(
56
54
  node_id=node_id,
57
55
  input_name="code",
58
56
  value=code_value,
59
57
  display_context=display_context,
60
- input_id=self.code_input_id,
58
+ input_id=code_input_id,
61
59
  )
60
+
61
+ runtime_input_id = self.node_input_ids_by_name.get(CodeExecutionNode.runtime.name)
62
62
  runtime_node_input = create_node_input(
63
63
  node_id=node_id,
64
64
  input_name="runtime",
65
65
  value=node.runtime,
66
66
  display_context=display_context,
67
- input_id=self.runtime_input_id,
67
+ input_id=runtime_input_id,
68
68
  )
69
69
  inputs.extend([code_node_input, runtime_node_input])
70
70
 
@@ -84,8 +84,8 @@ class BaseCodeExecutionNodeDisplay(BaseNodeVellumDisplay[_CodeExecutionNodeType]
84
84
  "error_output_id": str(error_output_id) if error_output_id else None,
85
85
  "source_handle_id": str(self.get_source_handle_id(display_context.port_displays)),
86
86
  "target_handle_id": str(self.get_target_handle_id()),
87
- "code_input_id": str(self.code_input_id) if self.code_input_id else code_node_input.id,
88
- "runtime_input_id": str(self.runtime_input_id) if self.runtime_input_id else runtime_node_input.id,
87
+ "code_input_id": code_node_input.id,
88
+ "runtime_input_id": runtime_node_input.id,
89
89
  "output_type": output_type,
90
90
  "packages": [package.dict() for package in packages] if packages is not None else [],
91
91
  "output_id": str(self.output_id) if self.output_id else str(output_display.id),
@@ -1,12 +1,16 @@
1
+ import pytest
1
2
  from uuid import uuid4
3
+ from typing import List
2
4
 
3
5
  from deepdiff import DeepDiff
4
6
 
7
+ from vellum.client.types.chat_message import ChatMessage
5
8
  from vellum.workflows.inputs.base import BaseInputs
6
9
  from vellum.workflows.nodes.bases.base import BaseNode
7
10
  from vellum.workflows.references.constant import ConstantValueReference
8
11
  from vellum.workflows.references.lazy import LazyReference
9
12
  from vellum.workflows.references.vellum_secret import VellumSecretReference
13
+ from vellum.workflows.state.base import BaseState
10
14
  from vellum.workflows.workflows.base import BaseWorkflow
11
15
  from vellum_ee.workflows.display.base import WorkflowInputsDisplay
12
16
  from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
@@ -237,6 +241,33 @@ def test_serialize_node__workflow_input(serialize_node):
237
241
  )
238
242
 
239
243
 
244
+ def test_serialize_node__workflow_input_as_nested_chat_history():
245
+ # GIVEN workflow inputs as chat history
246
+ class Inputs(BaseInputs):
247
+ chat_history: List[ChatMessage]
248
+
249
+ # AND a node referencing the workflow input
250
+ class GenericNode(BaseNode):
251
+ attr = {
252
+ "hello": Inputs.chat_history,
253
+ }
254
+
255
+ # AND a workflow with the node
256
+ class Workflow(BaseWorkflow[Inputs, BaseState]):
257
+ graph = GenericNode
258
+
259
+ # WHEN the workflow is serialized
260
+ workflow_display = get_workflow_display(
261
+ base_display_class=VellumWorkflowDisplay,
262
+ workflow_class=Workflow,
263
+ )
264
+ with pytest.raises(Exception) as exc_info:
265
+ workflow_display.serialize()
266
+
267
+ # THEN we should raise a user facing error
268
+ assert str(exc_info.value) == "Failed to serialize attribute 'attr': Nested references are not supported."
269
+
270
+
240
271
  def test_serialize_node__node_output(serialize_node):
241
272
  class NodeWithOutput(BaseNode):
242
273
  class Outputs(BaseNode.Outputs):