vellum-ai 1.4.0__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.4.0",
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.4.0",
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(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 1.4.0
3
+ Version: 1.4.1
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -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=s31x1QZneMOjgCfxuF5_0xmRGacwTOb9n0pFobRD42Y,2840
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,7 +1914,7 @@ 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
1920
  vellum/workflows/nodes/tests/test_utils.py,sha256=6yn0ieMug-ndcPVR2Z0HLIAMuCuS-4ucKSMnx06qcEc,5674
@@ -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.4.0.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1991
- vellum_ai-1.4.0.dist-info/METADATA,sha256=tI2aW2bZkPjR4_UtYRBydLigbdq2Et_pWewZJw1aKLE,5547
1992
- vellum_ai-1.4.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1993
- vellum_ai-1.4.0.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1994
- vellum_ai-1.4.0.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,,