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.
- vellum/client/core/client_wrapper.py +2 -2
- vellum/workflows/events/exception_handling.py +58 -0
- vellum/workflows/events/tests/test_event.py +27 -0
- vellum/workflows/exceptions.py +11 -6
- vellum/workflows/inputs/base.py +1 -0
- vellum/workflows/nodes/mocks.py +15 -4
- {vellum_ai-1.4.0.dist-info → vellum_ai-1.4.1.dist-info}/METADATA +1 -1
- {vellum_ai-1.4.0.dist-info → vellum_ai-1.4.1.dist-info}/RECORD +11 -10
- {vellum_ai-1.4.0.dist-info → vellum_ai-1.4.1.dist-info}/LICENSE +0 -0
- {vellum_ai-1.4.0.dist-info → vellum_ai-1.4.1.dist-info}/WHEEL +0 -0
- {vellum_ai-1.4.0.dist-info → vellum_ai-1.4.1.dist-info}/entry_points.txt +0 -0
@@ -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.
|
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.
|
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
|
vellum/workflows/exceptions.py
CHANGED
@@ -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__(
|
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)
|
vellum/workflows/inputs/base.py
CHANGED
@@ -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
|
vellum/workflows/nodes/mocks.py
CHANGED
@@ -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(
|
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(
|
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 {
|
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: {
|
238
|
+
message=f"Unsupported resolved output reference type: {ref_type}",
|
239
|
+
workflow_definition=workflow,
|
229
240
|
)
|
230
241
|
|
231
242
|
mock_node_executions.append(
|
@@ -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=
|
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=
|
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=
|
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=
|
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=
|
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.
|
1991
|
-
vellum_ai-1.4.
|
1992
|
-
vellum_ai-1.4.
|
1993
|
-
vellum_ai-1.4.
|
1994
|
-
vellum_ai-1.4.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|