vellum-ai 1.3.11__py3-none-any.whl → 1.4.1__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.
@@ -27,10 +27,10 @@ class BaseClientWrapper:
27
27
 
28
28
  def get_headers(self) -> typing.Dict[str, str]:
29
29
  headers: typing.Dict[str, str] = {
30
- "User-Agent": "vellum-ai/1.3.11",
30
+ "User-Agent": "vellum-ai/1.4.1",
31
31
  "X-Fern-Language": "Python",
32
32
  "X-Fern-SDK-Name": "vellum-ai",
33
- "X-Fern-SDK-Version": "1.3.11",
33
+ "X-Fern-SDK-Version": "1.4.1",
34
34
  **(self.get_custom_headers() or {}),
35
35
  }
36
36
  if self._api_version is not None:
@@ -0,0 +1,58 @@
1
+ from uuid import uuid4
2
+ from typing import Generator
3
+
4
+ from vellum.workflows.context import get_execution_context
5
+ from vellum.workflows.events.stream import WorkflowEventGenerator
6
+ from vellum.workflows.events.workflow import (
7
+ WorkflowEvent,
8
+ WorkflowEventStream,
9
+ WorkflowExecutionInitiatedBody,
10
+ WorkflowExecutionInitiatedEvent,
11
+ WorkflowExecutionRejectedBody,
12
+ WorkflowExecutionRejectedEvent,
13
+ )
14
+ from vellum.workflows.exceptions import WorkflowInitializationException
15
+ from vellum.workflows.inputs import BaseInputs
16
+
17
+
18
+ def stream_initialization_exception(
19
+ exception: WorkflowInitializationException,
20
+ ) -> WorkflowEventStream:
21
+ """
22
+ Stream a workflow initiated event followed by a workflow rejected event for an initialization exception.
23
+
24
+ Args:
25
+ exception: The WorkflowInitializationException to stream events for
26
+
27
+ Returns:
28
+ WorkflowEventGenerator yielding initiated and rejected events
29
+ """
30
+
31
+ execution_context = get_execution_context()
32
+ span_id = uuid4()
33
+
34
+ def _generate_events() -> Generator[WorkflowEvent, None, None]:
35
+ initiated_event: WorkflowEvent = WorkflowExecutionInitiatedEvent(
36
+ trace_id=execution_context.trace_id,
37
+ span_id=span_id,
38
+ body=WorkflowExecutionInitiatedBody(
39
+ workflow_definition=exception.definition,
40
+ inputs=BaseInputs(),
41
+ initial_state=None,
42
+ ),
43
+ parent=execution_context.parent_context,
44
+ )
45
+ yield initiated_event
46
+
47
+ rejected_event = WorkflowExecutionRejectedEvent(
48
+ trace_id=execution_context.trace_id,
49
+ span_id=span_id,
50
+ body=WorkflowExecutionRejectedBody(
51
+ workflow_definition=exception.definition,
52
+ error=exception.error,
53
+ ),
54
+ parent=execution_context.parent_context,
55
+ )
56
+ yield rejected_event
57
+
58
+ return WorkflowEventGenerator(_generate_events(), span_id)
@@ -7,6 +7,7 @@ from deepdiff import DeepDiff
7
7
  from vellum.client.core.pydantic_utilities import UniversalBaseModel
8
8
  from vellum.workflows.constants import undefined
9
9
  from vellum.workflows.errors.types import WorkflowError, WorkflowErrorCode
10
+ from vellum.workflows.events.exception_handling import stream_initialization_exception
10
11
  from vellum.workflows.events.node import (
11
12
  NodeExecutionFulfilledBody,
12
13
  NodeExecutionFulfilledEvent,
@@ -26,6 +27,7 @@ from vellum.workflows.events.workflow import (
26
27
  WorkflowExecutionStreamingBody,
27
28
  WorkflowExecutionStreamingEvent,
28
29
  )
30
+ from vellum.workflows.exceptions import WorkflowInitializationException
29
31
  from vellum.workflows.inputs.base import BaseInputs
30
32
  from vellum.workflows.nodes.bases.base import BaseNode
31
33
  from vellum.workflows.outputs.base import BaseOutput
@@ -460,3 +462,28 @@ def test_parent_context__deserialize_from_json__invalid_parent_context():
460
462
  assert event.parent.type == "UNKNOWN"
461
463
  assert event.parent.span_id == UUID("123e4567-e89b-12d3-a456-426614174000")
462
464
  assert event.parent.parent is None
465
+
466
+
467
+ def test_workflow_event_generator_stream_initialization_exception():
468
+ """
469
+ Tests that stream_initialization_exception yields both initiated and rejected events with proper correlation.
470
+ """
471
+ exception = WorkflowInitializationException("Test initialization error", workflow_definition=MockWorkflow)
472
+
473
+ events = list(stream_initialization_exception(exception))
474
+
475
+ assert len(events) == 2
476
+
477
+ initiated_event = events[0]
478
+ assert initiated_event.name == "workflow.execution.initiated"
479
+ assert initiated_event.body.inputs is not None
480
+ assert initiated_event.body.initial_state is None
481
+ assert initiated_event.body.workflow_definition == MockWorkflow
482
+
483
+ rejected_event = events[1]
484
+ assert rejected_event.name == "workflow.execution.rejected"
485
+ assert rejected_event.body.error.message == "Test initialization error"
486
+ assert rejected_event.body.workflow_definition == MockWorkflow
487
+
488
+ assert initiated_event.trace_id == rejected_event.trace_id
489
+ assert initiated_event.span_id == rejected_event.span_id
@@ -1,7 +1,10 @@
1
- from typing import Any, Dict, Optional
1
+ from typing import TYPE_CHECKING, Any, Dict, Optional, Type
2
2
 
3
3
  from vellum.workflows.errors import WorkflowError, WorkflowErrorCode
4
4
 
5
+ if TYPE_CHECKING:
6
+ from vellum.workflows.workflows.base import BaseWorkflow
7
+
5
8
 
6
9
  class NodeException(Exception):
7
10
  def __init__(
@@ -29,9 +32,15 @@ class NodeException(Exception):
29
32
 
30
33
 
31
34
  class WorkflowInitializationException(Exception):
32
- def __init__(self, message: str, code: WorkflowErrorCode = WorkflowErrorCode.INVALID_INPUTS):
35
+ def __init__(
36
+ self,
37
+ message: str,
38
+ workflow_definition: Type["BaseWorkflow"],
39
+ code: WorkflowErrorCode = WorkflowErrorCode.INVALID_INPUTS,
40
+ ):
33
41
  self.message = message
34
42
  self.code = code
43
+ self.definition = workflow_definition
35
44
  super().__init__(message)
36
45
 
37
46
  @property
@@ -40,7 +49,3 @@ class WorkflowInitializationException(Exception):
40
49
  message=self.message,
41
50
  code=self.code,
42
51
  )
43
-
44
- @staticmethod
45
- def of(workflow_error: WorkflowError) -> "WorkflowInitializationException":
46
- return WorkflowInitializationException(message=workflow_error.message, code=workflow_error.code)
@@ -95,6 +95,7 @@ class BaseInputs(metaclass=_BaseInputsMeta):
95
95
  raise WorkflowInitializationException(
96
96
  message=f"Required input variables {name} should have defined value",
97
97
  code=WorkflowErrorCode.INVALID_INPUTS,
98
+ workflow_definition=self.__class__.__parent_class__,
98
99
  )
99
100
 
100
101
  # If value provided in kwargs, set it on the instance
@@ -123,6 +123,7 @@ class MockNodeExecution(UniversalBaseModel):
123
123
  raise WorkflowInitializationException(
124
124
  message="Failed to validate mock node executions",
125
125
  code=WorkflowErrorCode.INVALID_INPUTS,
126
+ workflow_definition=workflow,
126
127
  ) from e
127
128
 
128
129
  nodes = {node.__id__: node for node in workflow.get_nodes()}
@@ -186,7 +187,10 @@ class MockNodeExecution(UniversalBaseModel):
186
187
  elif raw_logical_condition.operator == "!=":
187
188
  return lhs.does_not_equal(rhs)
188
189
  else:
189
- raise WorkflowInitializationException(f"Unsupported logical operator: {raw_logical_condition.operator}")
190
+ raise WorkflowInitializationException(
191
+ message=f"Unsupported logical operator: {raw_logical_condition.operator}",
192
+ workflow_definition=workflow,
193
+ )
190
194
 
191
195
  def _translate_raw_logical_expression_variable(
192
196
  raw_variable: _RawMockWorkflowNodeExecutionValuePointer,
@@ -197,7 +201,10 @@ class MockNodeExecution(UniversalBaseModel):
197
201
  node = nodes[raw_variable.node_id]
198
202
  return node.Execution.count
199
203
  else:
200
- raise WorkflowInitializationException(f"Unsupported logical expression type: {raw_variable.type}")
204
+ raise WorkflowInitializationException(
205
+ message=f"Unsupported logical expression type: {raw_variable.type}",
206
+ workflow_definition=workflow,
207
+ )
201
208
 
202
209
  mock_node_executions = []
203
210
  for mock_workflow_node_config in mock_workflow_node_configs:
@@ -212,8 +219,10 @@ class MockNodeExecution(UniversalBaseModel):
212
219
  for then_output in mock_execution.then_outputs:
213
220
  node_output_name = node_output_name_by_id.get(then_output.output_id)
214
221
  if node_output_name is None:
222
+ node_id = mock_workflow_node_config.node_id
215
223
  raise WorkflowInitializationException(
216
- f"Output {then_output.output_id} not found in node {mock_workflow_node_config.node_id}"
224
+ message=f"Output {then_output.output_id} not found in node {node_id}",
225
+ workflow_definition=workflow,
217
226
  )
218
227
 
219
228
  resolved_output_reference = _translate_raw_logical_expression_variable(then_output.value)
@@ -224,8 +233,10 @@ class MockNodeExecution(UniversalBaseModel):
224
233
  resolved_output_reference._value,
225
234
  )
226
235
  else:
236
+ ref_type = type(resolved_output_reference)
227
237
  raise WorkflowInitializationException(
228
- f"Unsupported resolved output reference type: {type(resolved_output_reference)}"
238
+ message=f"Unsupported resolved output reference type: {ref_type}",
239
+ workflow_definition=workflow,
229
240
  )
230
241
 
231
242
  mock_node_executions.append(
@@ -86,23 +86,23 @@ def test_parse_type_from_str_list_of_models():
86
86
  List[str],
87
87
  NodeException,
88
88
  WorkflowErrorCode.INVALID_OUTPUTS,
89
- "Invalid JSON Array format for result_as_str",
89
+ "Invalid JSON format: expected a valid JSON array",
90
90
  ),
91
91
  (
92
92
  "{invalid json}",
93
93
  Person,
94
94
  NodeException,
95
95
  WorkflowErrorCode.INVALID_OUTPUTS,
96
- "Invalid JSON format for result_as_str",
96
+ "Invalid JSON format: unable to parse the provided data",
97
97
  ),
98
98
  (
99
99
  "{invalid json}",
100
100
  Json,
101
101
  NodeException,
102
102
  WorkflowErrorCode.INVALID_OUTPUTS,
103
- "Invalid JSON format for result_as_str",
103
+ "Invalid JSON format: unable to parse the provided data",
104
104
  ),
105
- ('{"name": "Alice"}', List[str], ValueError, None, "Expected a list of items for result_as_str, received dict"),
105
+ ('{"name": "Alice"}', List[str], ValueError, None, "Expected a list of items, but received dict"),
106
106
  ("data", object, ValueError, None, "Unsupported output type: <class 'object'>"),
107
107
  ],
108
108
  ids=[
@@ -129,11 +129,11 @@ def parse_type_from_str(result_as_str: str, output_type: Any) -> Any:
129
129
  # raise ValueError("Invalid JSON Array format for result_as_str")
130
130
  raise NodeException(
131
131
  code=WorkflowErrorCode.INVALID_OUTPUTS,
132
- message="Invalid JSON Array format for result_as_str",
132
+ message="Invalid JSON format: expected a valid JSON array",
133
133
  )
134
134
 
135
135
  if not isinstance(data, list):
136
- raise ValueError(f"Expected a list of items for result_as_str, received {data.__class__.__name__}")
136
+ raise ValueError(f"Expected a list of items, but received {data.__class__.__name__}")
137
137
 
138
138
  inner_type = get_args(output_type)[0]
139
139
  if issubclass(inner_type, BaseModel):
@@ -151,7 +151,7 @@ def parse_type_from_str(result_as_str: str, output_type: Any) -> Any:
151
151
  except json.JSONDecodeError:
152
152
  raise NodeException(
153
153
  code=WorkflowErrorCode.INVALID_OUTPUTS,
154
- message="Invalid JSON format for result_as_str",
154
+ message="Invalid JSON format: unable to parse the provided data",
155
155
  )
156
156
 
157
157
  if get_origin(output_type) is Union:
@@ -177,7 +177,7 @@ def parse_type_from_str(result_as_str: str, output_type: Any) -> Any:
177
177
  except json.JSONDecodeError:
178
178
  raise NodeException(
179
179
  code=WorkflowErrorCode.INVALID_OUTPUTS,
180
- message="Invalid JSON format for result_as_str",
180
+ message="Invalid JSON format: unable to parse the provided data",
181
181
  )
182
182
 
183
183
  raise ValueError(f"Unsupported output type: {output_type}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 1.3.11
3
+ Version: 1.4.1
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -121,7 +121,7 @@ vellum_ee/workflows/display/utils/tests/test_events.py,sha256=42IEBnMbaQrH8gigw5
121
121
  vellum_ee/workflows/display/utils/vellum.py,sha256=sZwU0KdmZZTKWW62SyxJTl2tC8tN6p_BpZ-lDoinV-U,5670
122
122
  vellum_ee/workflows/display/vellum.py,sha256=J2mdJZ1sdLW535DDUkq_Vm8Z572vhuxHxVZF9deKSdk,391
123
123
  vellum_ee/workflows/display/workflows/__init__.py,sha256=JTB9ObEV3l4gGGdtfBHwVJtTTKC22uj-a-XjTVwXCyA,148
124
- vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=4aC042Fmy9h-QUD6Z6inLbrR-7wE0t_V3NMb44Y0wek,43692
124
+ vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=tlhtdNFT4_NJlBDkcn13CQOA49iy6d1F7kl5ONq21Rw,44032
125
125
  vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=gxz76AeCqgAZ9D2lZeTiZzxY9eMgn3qOSfVgiqYcOh8,2028
126
126
  vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=OKf_WVoPkYPrielOz8CyI5AjWt9MS2nSbWQKpF7HSLI,37847
127
127
  vellum_ee/workflows/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -147,7 +147,7 @@ vellum_ee/workflows/tests/local_workflow/nodes/templating_node.py,sha256=NQwFN61
147
147
  vellum_ee/workflows/tests/local_workflow/workflow.py,sha256=A4qOzOPNwePYxWbcAgIPLsmrVS_aVEZEc-wULSv787Q,393
148
148
  vellum_ee/workflows/tests/test_display_meta.py,sha256=PkXJVnMZs9GNooDkd59n4YTBAX3XGPQWeSSVbhehVFM,5112
149
149
  vellum_ee/workflows/tests/test_registry.py,sha256=B8xRIuEyLWfSqrYoPldNQXhKPfe50PllvtAZoI8-uPs,6066
150
- vellum_ee/workflows/tests/test_serialize_module.py,sha256=lk-4dVnG2HcxxywBXxDR1ieH8D9RJt4lvchoZhtQPdU,2892
150
+ vellum_ee/workflows/tests/test_serialize_module.py,sha256=d4ZpMd3oIxiq-sBXeSQESS6ix6-1P6rdCRFqBEReJIU,2882
151
151
  vellum_ee/workflows/tests/test_server.py,sha256=dXFBraU99Y6cKp2aBhLFXQTScSRcE9WaWjo1z9piqdU,23344
152
152
  vellum_ee/workflows/tests/test_virtual_files.py,sha256=TJEcMR0v2S8CkloXNmCHA0QW0K6pYNGaIjraJz7sFvY,2762
153
153
  vellum/__init__.py,sha256=lv4OTbPgTegugVOpRy5xJPPwMvC1Zqrg4oFMEwY1KSg,47428
@@ -155,7 +155,7 @@ vellum/client/README.md,sha256=flqu57ubZNTfpq60CdLtJC9gp4WEkyjb_n_eZ4OYf9w,6497
155
155
  vellum/client/__init__.py,sha256=T5Ht_w-Mk_9nzGqdadhQB8V20M0vYj7am06ut0A3P1o,73401
156
156
  vellum/client/core/__init__.py,sha256=lTcqUPXcx4112yLDd70RAPeqq6tu3eFMe1pKOqkW9JQ,1562
157
157
  vellum/client/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
158
- vellum/client/core/client_wrapper.py,sha256=jUohtsg67ju5RCuUUwRLdh1g44h86JtrmqbDsIJDNts,2842
158
+ vellum/client/core/client_wrapper.py,sha256=llxvaMOp54YJE6Vhu9cPaMURRdf9SIRPapzoEfyMqi0,2840
159
159
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
160
160
  vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
161
161
  vellum/client/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
@@ -1734,15 +1734,16 @@ vellum/workflows/errors/__init__.py,sha256=tWGPu5xyAU8gRb8_bl0fL7OfU3wxQ9UH6qVwy
1734
1734
  vellum/workflows/errors/types.py,sha256=1LQzsEwCL-kqLGUxZcgJWahL-XNfIOwCz_5f_fWzLrM,4236
1735
1735
  vellum/workflows/events/__init__.py,sha256=V4mh766fyA70WvHelm9kfVZGrUgEKcJ9tJt8EepfQYU,832
1736
1736
  vellum/workflows/events/context.py,sha256=vCfMIPmz4j9Om36rRWa35A_JU_VccWWS52_mZkkqxak,3345
1737
+ vellum/workflows/events/exception_handling.py,sha256=2okFtCzrOzaCP-HEwBPMvHn-evlyyE1zRkmIYjR__jQ,1975
1737
1738
  vellum/workflows/events/node.py,sha256=yHVd-rX2E3qc2XLnZr0fW6uq4ZCMm34mnY2tzYceyOg,5884
1738
1739
  vellum/workflows/events/relational_threads.py,sha256=zmLrBCBYpdpQV0snKH3HleST-_hWAMy2LIT0xScfzi4,1516
1739
1740
  vellum/workflows/events/stream.py,sha256=xhXJTZirFi0xad5neAQNogrIQ4h47fpnKbVC3vCM5Js,889
1740
1741
  vellum/workflows/events/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1741
1742
  vellum/workflows/events/tests/test_basic_workflow.py,sha256=Pj6orHsXz37jWC5FARi0Sx2Gjf99Owri2Cvr6Chb79k,1765
1742
- vellum/workflows/events/tests/test_event.py,sha256=RGVGz0DXMTvwCgdjua8rpPpCuCLDM5-8ET_3q4yH8_8,18493
1743
+ vellum/workflows/events/tests/test_event.py,sha256=jsC8APdrddLs5ejk9NO0waPLLslsJlBMIvN0M_vpAHI,19692
1743
1744
  vellum/workflows/events/types.py,sha256=mVrqAH9Hs9SpXm08Hcxdyap_ImQPwGsxRr56rSNMP34,5043
1744
1745
  vellum/workflows/events/workflow.py,sha256=kLSWFXiDZH0TELWoDjQ_kHVomFnw8MVVUPDGIzgyosw,8997
1745
- vellum/workflows/exceptions.py,sha256=Y7EULLN0kss8jxTLFNWEiOLMnyr1uKG83wiMvmtQ9Ak,1438
1746
+ vellum/workflows/exceptions.py,sha256=jyqfR-oq6iMAXSqaOexc-RjL1uFVEuxgcZ_r8AMaAn8,1463
1746
1747
  vellum/workflows/executable.py,sha256=um-gLJMVYfGJwGJfZIPlCRHhHIYm6pn8PUEfeqrNx5k,218
1747
1748
  vellum/workflows/expressions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1748
1749
  vellum/workflows/expressions/accessor.py,sha256=3lu1-_-dBfZdJvtX-q66jbmRAZtqIfdsh_3_JNuzg1E,4462
@@ -1793,7 +1794,7 @@ vellum/workflows/graph/graph.py,sha256=vkpteMc2a61IFGHlrA50J4ntVj6m3agcyWrXGQEbj
1793
1794
  vellum/workflows/graph/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1794
1795
  vellum/workflows/graph/tests/test_graph.py,sha256=0Pov0sCsxjzUDL9wy7xy9jFD-F2GsMJnZVEVFXzQGdM,15433
1795
1796
  vellum/workflows/inputs/__init__.py,sha256=02pj0IbJkN1AxTreswK39cNi45tA8GWcAAdRJve4cuM,116
1796
- vellum/workflows/inputs/base.py,sha256=w3owT5B3rLBmIj-v-jL2l-HD4yd3hXK9RmHVd557BpA,5126
1797
+ vellum/workflows/inputs/base.py,sha256=4kCRVz8AOqL6NgWZlfsBMnmCeDGDCTU0ImyBLlB0oaE,5203
1797
1798
  vellum/workflows/inputs/dataset_row.py,sha256=T8lcn9qyC7IY0w3EIfnn4AwZ3pYw9sf4kdIi0VkX_Sw,1033
1798
1799
  vellum/workflows/inputs/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1799
1800
  vellum/workflows/inputs/tests/test_inputs.py,sha256=lioA8917mFLYq7Ml69UNkqUjcWbbxkxnpIEJ4FBaYBk,2206
@@ -1913,11 +1914,11 @@ vellum/workflows/nodes/experimental/README.md,sha256=eF6DfIL8t-HbF9-mcofOMymKrra
1913
1914
  vellum/workflows/nodes/experimental/__init__.py,sha256=jCQgvZEknXKfuNhGSOou4XPfrPqZ1_XBj5F0n0fgiWM,106
1914
1915
  vellum/workflows/nodes/experimental/openai_chat_completion_node/__init__.py,sha256=lsyD9laR9p7kx5-BXGH2gUTM242UhKy8SMV0SR6S2iE,90
1915
1916
  vellum/workflows/nodes/experimental/openai_chat_completion_node/node.py,sha256=cKI2Ls25L-JVt4z4a2ozQa-YBeVy21Z7BQ32Sj7iBPE,10460
1916
- vellum/workflows/nodes/mocks.py,sha256=a1FjWEIocseMfjzM-i8DNozpUsaW0IONRpZmXBoWlyc,10455
1917
+ vellum/workflows/nodes/mocks.py,sha256=FXvP049s1KuilDqjUub12Y81rjR9vgPdX8pu6oBSjoE,10931
1917
1918
  vellum/workflows/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1918
1919
  vellum/workflows/nodes/tests/test_mocks.py,sha256=mfPvrs75PKcsNsbJLQAN6PDFoVqs9TmQxpdyFKDdO60,7837
1919
- vellum/workflows/nodes/tests/test_utils.py,sha256=BUugAHx2C9YuCwTlsTXV1Glxca0kW3St6T9o_QFatSU,5649
1920
- vellum/workflows/nodes/utils.py,sha256=wCvf8K5qruT5GwtvnHcQ-LMllktTD8aaFmAGpKQy--c,10720
1920
+ vellum/workflows/nodes/tests/test_utils.py,sha256=6yn0ieMug-ndcPVR2Z0HLIAMuCuS-4ucKSMnx06qcEc,5674
1921
+ vellum/workflows/nodes/utils.py,sha256=4u7gJnJtI1CM0RmsS6c-edTeGrJvd340rDiEtP6jRlk,10745
1921
1922
  vellum/workflows/outputs/__init__.py,sha256=AyZ4pRh_ACQIGvkf0byJO46EDnSix1ZCAXfvh-ms1QE,94
1922
1923
  vellum/workflows/outputs/base.py,sha256=zy02zr9DmG3j7Xp3Q8xiOiXFF_c7uNh76jf2LiMS-qE,10132
1923
1924
  vellum/workflows/ports/__init__.py,sha256=bZuMt-R7z5bKwpu4uPW7LlJeePOQWmCcDSXe5frUY5g,101
@@ -1987,8 +1988,8 @@ vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnad
1987
1988
  vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1988
1989
  vellum/workflows/workflows/tests/test_base_workflow.py,sha256=ptMntHzVyy8ZuzNgeTuk7hREgKQ5UBdgq8VJFSGaW4Y,20832
1989
1990
  vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
1990
- vellum_ai-1.3.11.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1991
- vellum_ai-1.3.11.dist-info/METADATA,sha256=OXKFjRVt9ymdiuFWO-WdvZ_lv_lWwiNYryNTEqoS054,5548
1992
- vellum_ai-1.3.11.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1993
- vellum_ai-1.3.11.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1994
- vellum_ai-1.3.11.dist-info/RECORD,,
1991
+ vellum_ai-1.4.1.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1992
+ vellum_ai-1.4.1.dist-info/METADATA,sha256=le27kYJhHlVpQr0IVs13TF46G-7YTLPVPtVPQtHsANk,5547
1993
+ vellum_ai-1.4.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1994
+ vellum_ai-1.4.1.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1995
+ vellum_ai-1.4.1.dist-info/RECORD,,
@@ -17,6 +17,7 @@ from vellum.workflows.descriptors.base import BaseDescriptor
17
17
  from vellum.workflows.edges import Edge
18
18
  from vellum.workflows.events.workflow import NodeEventDisplayContext, WorkflowEventDisplayContext
19
19
  from vellum.workflows.inputs.base import BaseInputs
20
+ from vellum.workflows.inputs.dataset_row import DatasetRow
20
21
  from vellum.workflows.nodes.bases import BaseNode
21
22
  from vellum.workflows.nodes.displayable.bases.utils import primitive_to_vellum_value
22
23
  from vellum.workflows.nodes.displayable.final_output_node.node import FinalOutputNode
@@ -913,7 +914,10 @@ class BaseWorkflowDisplay(Generic[WorkflowType]):
913
914
  if dataset_attr and isinstance(dataset_attr, list):
914
915
  dataset = []
915
916
  for i, inputs_obj in enumerate(dataset_attr):
916
- if isinstance(inputs_obj, BaseInputs):
917
+ if isinstance(inputs_obj, DatasetRow):
918
+ serialized_inputs = json.loads(json.dumps(inputs_obj.inputs, cls=DefaultStateEncoder))
919
+ dataset.append({"label": inputs_obj.label, "inputs": serialized_inputs})
920
+ elif isinstance(inputs_obj, BaseInputs):
917
921
  serialized_inputs = json.loads(json.dumps(inputs_obj, cls=DefaultStateEncoder))
918
922
  dataset.append({"label": f"Scenario {i + 1}", "inputs": serialized_inputs})
919
923
  except (ImportError, AttributeError):
@@ -24,12 +24,11 @@ def test_serialize_module_with_actual_dataset():
24
24
  assert isinstance(result.dataset, list)
25
25
  assert len(result.dataset) == 2
26
26
 
27
- for i, item in enumerate(result.dataset):
28
- assert "label" in item
29
- assert "inputs" in item
30
- assert item["label"] == f"Scenario {i + 1}"
31
- assert isinstance(item["inputs"], dict)
32
- assert "message" in item["inputs"]
27
+ assert result.dataset[0]["label"] == "Scenario 1"
28
+ assert result.dataset[0]["inputs"]["message"] == "World"
29
+
30
+ assert result.dataset[1]["label"] == "Custom Test"
31
+ assert result.dataset[1]["inputs"]["message"] == "DatasetRow Test"
33
32
 
34
33
 
35
34
  def test_serialize_module_happy_path():