vellum-ai 0.11.10__py3-none-any.whl → 0.12.0__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.
Files changed (61) hide show
  1. vellum/client/core/client_wrapper.py +1 -1
  2. vellum/workflows/descriptors/base.py +2 -2
  3. vellum/workflows/descriptors/tests/test_utils.py +4 -4
  4. vellum/workflows/errors/__init__.py +3 -3
  5. vellum/workflows/errors/types.py +46 -3
  6. vellum/workflows/events/node.py +3 -3
  7. vellum/workflows/events/tests/test_event.py +3 -3
  8. vellum/workflows/events/workflow.py +3 -3
  9. vellum/workflows/exceptions.py +8 -4
  10. vellum/workflows/nodes/bases/base.py +9 -2
  11. vellum/workflows/nodes/bases/tests/test_base_node.py +13 -0
  12. vellum/workflows/nodes/core/error_node/node.py +9 -5
  13. vellum/workflows/nodes/core/inline_subworkflow_node/node.py +3 -13
  14. vellum/workflows/nodes/core/map_node/node.py +2 -2
  15. vellum/workflows/nodes/core/retry_node/node.py +5 -5
  16. vellum/workflows/nodes/core/retry_node/tests/test_node.py +6 -6
  17. vellum/workflows/nodes/core/templating_node/node.py +2 -2
  18. vellum/workflows/nodes/core/try_node/node.py +7 -7
  19. vellum/workflows/nodes/core/try_node/tests/test_node.py +9 -7
  20. vellum/workflows/nodes/displayable/bases/api_node/node.py +3 -3
  21. vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +4 -12
  22. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +2 -2
  23. vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +2 -2
  24. vellum/workflows/nodes/displayable/bases/search_node.py +3 -3
  25. vellum/workflows/nodes/displayable/code_execution_node/node.py +6 -6
  26. vellum/workflows/nodes/displayable/guardrail_node/node.py +3 -3
  27. vellum/workflows/nodes/displayable/inline_prompt_node/node.py +3 -3
  28. vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +3 -3
  29. vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +7 -14
  30. vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py +4 -4
  31. vellum/workflows/nodes/utils.py +5 -9
  32. vellum/workflows/references/external_input.py +2 -2
  33. vellum/workflows/references/node.py +2 -2
  34. vellum/workflows/references/state_value.py +2 -2
  35. vellum/workflows/references/workflow_input.py +2 -2
  36. vellum/workflows/runner/runner.py +15 -15
  37. {vellum_ee/workflows/display → vellum/workflows}/utils/tests/test_uuids.py +1 -1
  38. vellum/workflows/workflows/base.py +7 -7
  39. {vellum_ai-0.11.10.dist-info → vellum_ai-0.12.0.dist-info}/METADATA +1 -1
  40. {vellum_ai-0.11.10.dist-info → vellum_ai-0.12.0.dist-info}/RECORD +60 -61
  41. vellum_ee/workflows/display/nodes/base_node_display.py +50 -21
  42. vellum_ee/workflows/display/nodes/base_node_vellum_display.py +1 -1
  43. vellum_ee/workflows/display/nodes/get_node_display_class.py +10 -1
  44. vellum_ee/workflows/display/nodes/tests/test_base_node_display.py +5 -4
  45. vellum_ee/workflows/display/nodes/vellum/code_execution_node.py +13 -6
  46. vellum_ee/workflows/display/nodes/vellum/conditional_node.py +1 -1
  47. vellum_ee/workflows/display/nodes/vellum/final_output_node.py +1 -1
  48. vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +1 -1
  49. vellum_ee/workflows/display/nodes/vellum/merge_node.py +4 -4
  50. vellum_ee/workflows/display/nodes/vellum/search_node.py +1 -1
  51. vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +5 -1
  52. vellum_ee/workflows/display/nodes/vellum/try_node.py +12 -6
  53. vellum_ee/workflows/display/nodes/vellum/utils.py +1 -1
  54. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +269 -85
  55. vellum_ee/workflows/display/workflows/base_workflow_display.py +2 -2
  56. vellum_ee/workflows/display/workflows/vellum_workflow_display.py +1 -1
  57. vellum_ee/workflows/display/utils/tests/__init__.py +0 -0
  58. {vellum_ee/workflows/display → vellum/workflows}/utils/uuids.py +0 -0
  59. {vellum_ai-0.11.10.dist-info → vellum_ai-0.12.0.dist-info}/LICENSE +0 -0
  60. {vellum_ai-0.11.10.dist-info → vellum_ai-0.12.0.dist-info}/WHEEL +0 -0
  61. {vellum_ai-0.11.10.dist-info → vellum_ai-0.12.0.dist-info}/entry_points.txt +0 -0
@@ -17,7 +17,7 @@ class BaseClientWrapper:
17
17
  headers: typing.Dict[str, str] = {
18
18
  "X-Fern-Language": "Python",
19
19
  "X-Fern-SDK-Name": "vellum-ai",
20
- "X-Fern-SDK-Version": "0.11.10",
20
+ "X-Fern-SDK-Version": "0.12.0",
21
21
  }
22
22
  headers["X_API_KEY"] = self.api_key
23
23
  return headers
@@ -258,12 +258,12 @@ class BaseDescriptor(Generic[_T]):
258
258
 
259
259
  return DoesNotEndWithExpression(lhs=self, rhs=other)
260
260
 
261
- def is_none(self) -> "IsNullExpression":
261
+ def is_null(self) -> "IsNullExpression":
262
262
  from vellum.workflows.expressions.is_null import IsNullExpression
263
263
 
264
264
  return IsNullExpression(expression=self)
265
265
 
266
- def is_not_none(self) -> "IsNotNullExpression":
266
+ def is_not_null(self) -> "IsNotNullExpression":
267
267
  from vellum.workflows.expressions.is_not_null import IsNotNullExpression
268
268
 
269
269
  return IsNotNullExpression(expression=self)
@@ -35,8 +35,8 @@ class FixtureState(BaseState):
35
35
  (FixtureState.gamma.does_not_contain(FixtureState.delta), False),
36
36
  (FixtureState.gamma.does_not_begin_with(FixtureState.delta), True),
37
37
  (FixtureState.gamma.does_not_end_with(FixtureState.delta), True),
38
- (FixtureState.alpha.is_none(), False),
39
- (FixtureState.alpha.is_not_none(), True),
38
+ (FixtureState.alpha.is_null(), False),
39
+ (FixtureState.alpha.is_not_null(), True),
40
40
  (FixtureState.delta.in_(FixtureState.gamma), True),
41
41
  (FixtureState.delta.not_in(FixtureState.gamma), False),
42
42
  (FixtureState.alpha.between(FixtureState.beta, FixtureState.epsilon), False),
@@ -66,8 +66,8 @@ class FixtureState(BaseState):
66
66
  "does_not_contain",
67
67
  "does_not_begin_with",
68
68
  "does_not_end_with",
69
- "is_none",
70
- "is_not_none",
69
+ "is_null",
70
+ "is_not_null",
71
71
  "in_",
72
72
  "not_in",
73
73
  "between",
@@ -1,6 +1,6 @@
1
- from .types import VellumError, VellumErrorCode
1
+ from .types import WorkflowError, WorkflowErrorCode
2
2
 
3
3
  __all__ = [
4
- "VellumError",
5
- "VellumErrorCode",
4
+ "WorkflowError",
5
+ "WorkflowErrorCode",
6
6
  ]
@@ -1,20 +1,63 @@
1
1
  from dataclasses import dataclass
2
2
  from enum import Enum
3
+ from typing import Dict
3
4
 
5
+ from vellum.client.types.vellum_error import VellumError
6
+ from vellum.client.types.vellum_error_code_enum import VellumErrorCodeEnum
7
+ from vellum.client.types.workflow_event_error import WorkflowEventError
8
+ from vellum.client.types.workflow_execution_event_error_code import WorkflowExecutionEventErrorCode
4
9
 
5
- class VellumErrorCode(Enum):
10
+
11
+ class WorkflowErrorCode(Enum):
6
12
  INVALID_WORKFLOW = "INVALID_WORKFLOW"
7
13
  INVALID_INPUTS = "INVALID_INPUTS"
8
14
  INVALID_OUTPUTS = "INVALID_OUTPUTS"
9
15
  INVALID_STATE = "INVALID_STATE"
10
16
  INVALID_TEMPLATE = "INVALID_TEMPLATE"
11
17
  INTERNAL_ERROR = "INTERNAL_ERROR"
18
+ NODE_EXECUTION = "NODE_EXECUTION"
12
19
  PROVIDER_ERROR = "PROVIDER_ERROR"
13
20
  USER_DEFINED_ERROR = "USER_DEFINED_ERROR"
14
21
  WORKFLOW_CANCELLED = "WORKFLOW_CANCELLED"
15
22
 
16
23
 
17
24
  @dataclass(frozen=True)
18
- class VellumError:
25
+ class WorkflowError:
19
26
  message: str
20
- code: VellumErrorCode
27
+ code: WorkflowErrorCode
28
+
29
+
30
+ _VELLUM_ERROR_CODE_TO_WORKFLOW_ERROR_CODE: Dict[VellumErrorCodeEnum, WorkflowErrorCode] = {
31
+ "INVALID_REQUEST": WorkflowErrorCode.INVALID_INPUTS,
32
+ "INVALID_INPUTS": WorkflowErrorCode.INVALID_INPUTS,
33
+ "PROVIDER_ERROR": WorkflowErrorCode.PROVIDER_ERROR,
34
+ "REQUEST_TIMEOUT": WorkflowErrorCode.PROVIDER_ERROR,
35
+ "INTERNAL_SERVER_ERROR": WorkflowErrorCode.INTERNAL_ERROR,
36
+ "USER_DEFINED_ERROR": WorkflowErrorCode.USER_DEFINED_ERROR,
37
+ }
38
+
39
+
40
+ def vellum_error_to_workflow_error(error: VellumError) -> WorkflowError:
41
+ return WorkflowError(
42
+ message=error.message,
43
+ code=_VELLUM_ERROR_CODE_TO_WORKFLOW_ERROR_CODE.get(error.code, WorkflowErrorCode.INTERNAL_ERROR),
44
+ )
45
+
46
+
47
+ _WORKFLOW_EVENT_ERROR_CODE_TO_WORKFLOW_ERROR_CODE: Dict[WorkflowExecutionEventErrorCode, WorkflowErrorCode] = {
48
+ "WORKFLOW_INITIALIZATION": WorkflowErrorCode.INVALID_WORKFLOW,
49
+ "WORKFLOW_CANCELLED": WorkflowErrorCode.WORKFLOW_CANCELLED,
50
+ "NODE_EXECUTION_COUNT_LIMIT_REACHED": WorkflowErrorCode.INVALID_STATE,
51
+ "INTERNAL_SERVER_ERROR": WorkflowErrorCode.INTERNAL_ERROR,
52
+ "NODE_EXECUTION": WorkflowErrorCode.NODE_EXECUTION,
53
+ "LLM_PROVIDER": WorkflowErrorCode.PROVIDER_ERROR,
54
+ "INVALID_TEMPLATE": WorkflowErrorCode.INVALID_TEMPLATE,
55
+ "USER_DEFINED_ERROR": WorkflowErrorCode.USER_DEFINED_ERROR,
56
+ }
57
+
58
+
59
+ def workflow_event_error_to_workflow_error(error: WorkflowEventError) -> WorkflowError:
60
+ return WorkflowError(
61
+ message=error.message,
62
+ code=_WORKFLOW_EVENT_ERROR_CODE_TO_WORKFLOW_ERROR_CODE.get(error.code, WorkflowErrorCode.INTERNAL_ERROR),
63
+ )
@@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any, Dict, Generic, List, Literal, Optional, S
3
3
  from pydantic import SerializerFunctionWrapHandler, field_serializer, model_serializer
4
4
 
5
5
  from vellum.core.pydantic_utilities import UniversalBaseModel
6
- from vellum.workflows.errors import VellumError
6
+ from vellum.workflows.errors import WorkflowError
7
7
  from vellum.workflows.expressions.accessor import AccessorExpression
8
8
  from vellum.workflows.outputs.base import BaseOutput
9
9
  from vellum.workflows.ports.port import Port
@@ -119,7 +119,7 @@ class NodeExecutionFulfilledEvent(_BaseNodeEvent, Generic[OutputsType]):
119
119
 
120
120
 
121
121
  class NodeExecutionRejectedBody(_BaseNodeExecutionBody):
122
- error: VellumError
122
+ error: WorkflowError
123
123
 
124
124
 
125
125
  class NodeExecutionRejectedEvent(_BaseNodeEvent):
@@ -127,7 +127,7 @@ class NodeExecutionRejectedEvent(_BaseNodeEvent):
127
127
  body: NodeExecutionRejectedBody
128
128
 
129
129
  @property
130
- def error(self) -> VellumError:
130
+ def error(self) -> WorkflowError:
131
131
  return self.body.error
132
132
 
133
133
 
@@ -4,7 +4,7 @@ from uuid import UUID
4
4
 
5
5
  from deepdiff import DeepDiff
6
6
 
7
- from vellum.workflows.errors.types import VellumError, VellumErrorCode
7
+ from vellum.workflows.errors.types import WorkflowError, WorkflowErrorCode
8
8
  from vellum.workflows.events.node import (
9
9
  NodeExecutionFulfilledBody,
10
10
  NodeExecutionFulfilledEvent,
@@ -213,9 +213,9 @@ module_root = name_parts[: name_parts.index("events")]
213
213
  span_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
214
214
  body=WorkflowExecutionRejectedBody(
215
215
  workflow_definition=MockWorkflow,
216
- error=VellumError(
216
+ error=WorkflowError(
217
217
  message="Workflow failed",
218
- code=VellumErrorCode.USER_DEFINED_ERROR,
218
+ code=WorkflowErrorCode.USER_DEFINED_ERROR,
219
219
  ),
220
220
  ),
221
221
  ),
@@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any, Dict, Generator, Generic, Iterable, Liter
3
3
  from pydantic import field_serializer
4
4
 
5
5
  from vellum.core.pydantic_utilities import UniversalBaseModel
6
- from vellum.workflows.errors import VellumError
6
+ from vellum.workflows.errors import WorkflowError
7
7
  from vellum.workflows.outputs.base import BaseOutput
8
8
  from vellum.workflows.references import ExternalInputReference
9
9
  from vellum.workflows.types.generics import OutputsType, StateType, WorkflowInputsType
@@ -90,7 +90,7 @@ class WorkflowExecutionFulfilledEvent(_BaseWorkflowEvent, Generic[OutputsType]):
90
90
 
91
91
 
92
92
  class WorkflowExecutionRejectedBody(_BaseWorkflowExecutionBody):
93
- error: VellumError
93
+ error: WorkflowError
94
94
 
95
95
 
96
96
  class WorkflowExecutionRejectedEvent(_BaseWorkflowEvent):
@@ -98,7 +98,7 @@ class WorkflowExecutionRejectedEvent(_BaseWorkflowEvent):
98
98
  body: WorkflowExecutionRejectedBody
99
99
 
100
100
  @property
101
- def error(self) -> VellumError:
101
+ def error(self) -> WorkflowError:
102
102
  return self.body.error
103
103
 
104
104
 
@@ -1,15 +1,19 @@
1
- from vellum.workflows.errors import VellumError, VellumErrorCode
1
+ from vellum.workflows.errors import WorkflowError, WorkflowErrorCode
2
2
 
3
3
 
4
4
  class NodeException(Exception):
5
- def __init__(self, message: str, code: VellumErrorCode):
5
+ def __init__(self, message: str, code: WorkflowErrorCode):
6
6
  self.message = message
7
7
  self.code = code
8
8
  super().__init__(message)
9
9
 
10
10
  @property
11
- def error(self) -> VellumError:
12
- return VellumError(
11
+ def error(self) -> WorkflowError:
12
+ return WorkflowError(
13
13
  message=self.message,
14
14
  code=self.code,
15
15
  )
16
+
17
+ @staticmethod
18
+ def of(workflow_error: WorkflowError) -> "NodeException":
19
+ return NodeException(message=workflow_error.message, code=workflow_error.code)
@@ -7,7 +7,7 @@ from typing import Any, Dict, Generic, Iterator, Optional, Set, Tuple, Type, Typ
7
7
  from vellum.workflows.constants import UNDEF
8
8
  from vellum.workflows.descriptors.base import BaseDescriptor
9
9
  from vellum.workflows.descriptors.utils import is_unresolved, resolve_value
10
- from vellum.workflows.errors.types import VellumErrorCode
10
+ from vellum.workflows.errors.types import WorkflowErrorCode
11
11
  from vellum.workflows.exceptions import NodeException
12
12
  from vellum.workflows.graph import Graph
13
13
  from vellum.workflows.graph.graph import GraphTarget
@@ -23,6 +23,7 @@ from vellum.workflows.state.context import WorkflowContext
23
23
  from vellum.workflows.types.core import MergeBehavior
24
24
  from vellum.workflows.types.generics import StateType
25
25
  from vellum.workflows.types.utils import get_class_attr_names, get_original_base, infer_types
26
+ from vellum.workflows.utils.uuids import uuid4_from_hash
26
27
 
27
28
 
28
29
  def is_nested_class(nested: Any, parent: Type) -> bool:
@@ -99,6 +100,7 @@ class BaseNodeMeta(type):
99
100
  node_class.Execution.node_class = node_class
100
101
  node_class.Trigger.node_class = node_class
101
102
  node_class.ExternalInputs.__parent_class__ = node_class
103
+ node_class.__id__ = uuid4_from_hash(node_class.__qualname__)
102
104
  return node_class
103
105
 
104
106
  @property
@@ -213,6 +215,7 @@ class _BaseNodeExecutionMeta(type):
213
215
 
214
216
 
215
217
  class BaseNode(Generic[StateType], metaclass=BaseNodeMeta):
218
+ __id__: UUID = uuid4_from_hash(__qualname__)
216
219
  state: StateType
217
220
  _context: WorkflowContext
218
221
  _inputs: MappingProxyType[NodeReference, Any]
@@ -284,7 +287,7 @@ class BaseNode(Generic[StateType], metaclass=BaseNodeMeta):
284
287
 
285
288
  raise NodeException(
286
289
  message="Invalid Trigger Node Specification",
287
- code=VellumErrorCode.INVALID_INPUTS,
290
+ code=WorkflowErrorCode.INVALID_INPUTS,
288
291
  )
289
292
 
290
293
  class Execution(metaclass=_BaseNodeExecutionMeta):
@@ -352,3 +355,7 @@ class BaseNode(Generic[StateType], metaclass=BaseNodeMeta):
352
355
 
353
356
  def __repr__(self) -> str:
354
357
  return str(self.__class__)
358
+
359
+
360
+ class MyNode2(BaseNode):
361
+ pass
@@ -1,3 +1,4 @@
1
+ from uuid import UUID
1
2
  from typing import Optional
2
3
 
3
4
  from vellum.core.pydantic_utilities import UniversalBaseModel
@@ -122,3 +123,15 @@ def test_base_node__node_resolution__coalesce_constants():
122
123
 
123
124
  # THEN the node is initialized with the correct data
124
125
  assert node.value == "world"
126
+
127
+
128
+ def test_base_node__default_id():
129
+ # GIVEN a node
130
+ class MyNode(BaseNode):
131
+ pass
132
+
133
+ # WHEN the node is accessed
134
+ my_id = MyNode.__id__
135
+
136
+ # THEN it should equal the hash of `test_base_node__default_id.<locals>.MyNode`
137
+ assert my_id == UUID("8e71bea7-ce68-492f-9abe-477c788e6273")
@@ -1,6 +1,7 @@
1
1
  from typing import ClassVar, Union
2
2
 
3
- from vellum.workflows.errors.types import VellumError, VellumErrorCode
3
+ from vellum.client.types.vellum_error import VellumError
4
+ from vellum.workflows.errors.types import WorkflowError, WorkflowErrorCode, vellum_error_to_workflow_error
4
5
  from vellum.workflows.exceptions import NodeException
5
6
  from vellum.workflows.nodes.bases.base import BaseNode
6
7
 
@@ -12,15 +13,18 @@ class ErrorNode(BaseNode):
12
13
  error: Union[str, VellumError] - The error to raise.
13
14
  """
14
15
 
15
- error: ClassVar[Union[str, VellumError]]
16
+ error: ClassVar[Union[str, WorkflowError, VellumError]]
16
17
 
17
18
  def run(self) -> BaseNode.Outputs:
18
19
  if isinstance(self.error, str):
19
- raise NodeException(message=self.error, code=VellumErrorCode.USER_DEFINED_ERROR)
20
- elif isinstance(self.error, VellumError):
20
+ raise NodeException(message=self.error, code=WorkflowErrorCode.USER_DEFINED_ERROR)
21
+ elif isinstance(self.error, WorkflowError):
21
22
  raise NodeException(message=self.error.message, code=self.error.code)
23
+ elif isinstance(self.error, VellumError):
24
+ workflow_error = vellum_error_to_workflow_error(self.error)
25
+ raise NodeException(message=workflow_error.message, code=workflow_error.code)
22
26
  else:
23
27
  raise NodeException(
24
28
  message=f"Error node received an unexpected input type: {self.error.__class__}",
25
- code=VellumErrorCode.INVALID_INPUTS,
29
+ code=WorkflowErrorCode.INVALID_INPUTS,
26
30
  )
@@ -1,7 +1,7 @@
1
1
  from typing import TYPE_CHECKING, Generic, Iterator, Optional, Set, Type, TypeVar
2
2
 
3
3
  from vellum.workflows.context import execution_context, get_parent_context
4
- from vellum.workflows.errors.types import VellumErrorCode
4
+ from vellum.workflows.errors.types import WorkflowErrorCode
5
5
  from vellum.workflows.exceptions import NodeException
6
6
  from vellum.workflows.nodes.bases.base_subworkflow_node import BaseSubworkflowNode
7
7
  from vellum.workflows.outputs.base import BaseOutput, BaseOutputs
@@ -49,22 +49,12 @@ class InlineSubworkflowNode(BaseSubworkflowNode[StateType], Generic[StateType, W
49
49
  elif event.name == "workflow.execution.fulfilled":
50
50
  outputs = event.outputs
51
51
  elif event.name == "workflow.execution.rejected":
52
- error = event.error
53
- if error.code in VellumErrorCode._value2member_map_:
54
- raise NodeException(
55
- message=error.message,
56
- code=VellumErrorCode(error.code),
57
- )
58
- else:
59
- raise NodeException(
60
- message=error.message,
61
- code=VellumErrorCode.INTERNAL_ERROR,
62
- )
52
+ raise NodeException.of(event.error)
63
53
 
64
54
  if outputs is None:
65
55
  raise NodeException(
66
56
  message="Expected to receive outputs from Workflow Deployment",
67
- code=VellumErrorCode.INVALID_OUTPUTS,
57
+ code=WorkflowErrorCode.INVALID_OUTPUTS,
68
58
  )
69
59
 
70
60
  # For any outputs somehow in our final fulfilled outputs array,
@@ -5,7 +5,7 @@ from typing import TYPE_CHECKING, Callable, Dict, Generic, List, Optional, Tuple
5
5
 
6
6
  from vellum.workflows.context import execution_context, get_parent_context
7
7
  from vellum.workflows.descriptors.base import BaseDescriptor
8
- from vellum.workflows.errors.types import VellumErrorCode
8
+ from vellum.workflows.errors.types import WorkflowErrorCode
9
9
  from vellum.workflows.events.types import ParentContext
10
10
  from vellum.workflows.exceptions import NodeException
11
11
  from vellum.workflows.inputs.base import BaseInputs
@@ -88,7 +88,7 @@ class MapNode(BaseNode, Generic[StateType, MapNodeItemType]):
88
88
  break
89
89
  elif terminal_event.name == "workflow.execution.paused":
90
90
  raise NodeException(
91
- code=VellumErrorCode.INVALID_OUTPUTS,
91
+ code=WorkflowErrorCode.INVALID_OUTPUTS,
92
92
  message=f"Subworkflow unexpectedly paused on iteration {index}",
93
93
  )
94
94
  elif terminal_event.name == "workflow.execution.rejected":
@@ -1,6 +1,6 @@
1
1
  from typing import TYPE_CHECKING, Any, Callable, Dict, Generic, Optional, Type
2
2
 
3
- from vellum.workflows.errors.types import VellumErrorCode
3
+ from vellum.workflows.errors.types import WorkflowErrorCode
4
4
  from vellum.workflows.exceptions import NodeException
5
5
  from vellum.workflows.inputs.base import BaseInputs
6
6
  from vellum.workflows.nodes.bases import BaseNode
@@ -31,7 +31,7 @@ class RetryNode(BaseNode[StateType], Generic[StateType], metaclass=_RetryNodeMet
31
31
  """
32
32
 
33
33
  max_attempts: int
34
- retry_on_error_code: Optional[VellumErrorCode] = None
34
+ retry_on_error_code: Optional[WorkflowErrorCode] = None
35
35
  subworkflow: Type["BaseWorkflow[SubworkflowInputs, BaseState]"]
36
36
 
37
37
  class SubworkflowInputs(BaseInputs):
@@ -58,13 +58,13 @@ class RetryNode(BaseNode[StateType], Generic[StateType], metaclass=_RetryNodeMet
58
58
  return node_outputs
59
59
  elif terminal_event.name == "workflow.execution.paused":
60
60
  last_exception = NodeException(
61
- code=VellumErrorCode.INVALID_OUTPUTS,
61
+ code=WorkflowErrorCode.INVALID_OUTPUTS,
62
62
  message=f"Subworkflow unexpectedly paused on attempt {attempt_number}",
63
63
  )
64
64
  break
65
65
  elif self.retry_on_error_code and self.retry_on_error_code != terminal_event.error.code:
66
66
  last_exception = NodeException(
67
- code=VellumErrorCode.INVALID_OUTPUTS,
67
+ code=WorkflowErrorCode.INVALID_OUTPUTS,
68
68
  message=f"""Unexpected rejection on attempt {attempt_number}: {terminal_event.error.code.value}.
69
69
  Message: {terminal_event.error.message}""",
70
70
  )
@@ -76,7 +76,7 @@ Message: {terminal_event.error.message}""",
76
76
 
77
77
  @classmethod
78
78
  def wrap(
79
- cls, max_attempts: int, retry_on_error_code: Optional[VellumErrorCode] = None
79
+ cls, max_attempts: int, retry_on_error_code: Optional[WorkflowErrorCode] = None
80
80
  ) -> Callable[..., Type["RetryNode"]]:
81
81
  _max_attempts = max_attempts
82
82
  _retry_on_error_code = retry_on_error_code
@@ -1,6 +1,6 @@
1
1
  import pytest
2
2
 
3
- from vellum.workflows.errors.types import VellumErrorCode
3
+ from vellum.workflows.errors.types import WorkflowErrorCode
4
4
  from vellum.workflows.exceptions import NodeException
5
5
  from vellum.workflows.inputs.base import BaseInputs
6
6
  from vellum.workflows.nodes.bases import BaseNode
@@ -11,7 +11,7 @@ from vellum.workflows.state.base import BaseState, StateMeta
11
11
 
12
12
  def test_retry_node__retry_on_error_code__successfully_retried():
13
13
  # GIVEN a retry node that is configured to retry on PROVIDER_ERROR
14
- @RetryNode.wrap(max_attempts=3, retry_on_error_code=VellumErrorCode.PROVIDER_ERROR)
14
+ @RetryNode.wrap(max_attempts=3, retry_on_error_code=WorkflowErrorCode.PROVIDER_ERROR)
15
15
  class TestNode(BaseNode):
16
16
  attempt_number = RetryNode.SubworkflowInputs.attempt_number
17
17
 
@@ -20,7 +20,7 @@ def test_retry_node__retry_on_error_code__successfully_retried():
20
20
 
21
21
  def run(self) -> Outputs:
22
22
  if self.attempt_number < 3:
23
- raise NodeException(message="This will be retried", code=VellumErrorCode.PROVIDER_ERROR)
23
+ raise NodeException(message="This will be retried", code=WorkflowErrorCode.PROVIDER_ERROR)
24
24
 
25
25
  return self.Outputs(execution_count=self.attempt_number)
26
26
 
@@ -34,7 +34,7 @@ def test_retry_node__retry_on_error_code__successfully_retried():
34
34
 
35
35
  def test_retry_node__retry_on_error_code__missed():
36
36
  # GIVEN a retry node that is configured to retry on PROVIDER_ERROR
37
- @RetryNode.wrap(max_attempts=3, retry_on_error_code=VellumErrorCode.PROVIDER_ERROR)
37
+ @RetryNode.wrap(max_attempts=3, retry_on_error_code=WorkflowErrorCode.PROVIDER_ERROR)
38
38
  class TestNode(BaseNode):
39
39
  attempt_number = RetryNode.SubworkflowInputs.attempt_number
40
40
 
@@ -57,7 +57,7 @@ def test_retry_node__retry_on_error_code__missed():
57
57
  exc_info.value.message
58
58
  == "Unexpected rejection on attempt 1: INTERNAL_ERROR.\nMessage: This will not be retried"
59
59
  )
60
- assert exc_info.value.code == VellumErrorCode.INVALID_OUTPUTS
60
+ assert exc_info.value.code == WorkflowErrorCode.INVALID_OUTPUTS
61
61
 
62
62
 
63
63
  def test_retry_node__use_parent_inputs_and_state():
@@ -69,7 +69,7 @@ def test_retry_node__use_parent_inputs_and_state():
69
69
  bar: str
70
70
 
71
71
  # AND a retry node that uses the parent's inputs and state
72
- @RetryNode.wrap(max_attempts=3, retry_on_error_code=VellumErrorCode.PROVIDER_ERROR)
72
+ @RetryNode.wrap(max_attempts=3, retry_on_error_code=WorkflowErrorCode.PROVIDER_ERROR)
73
73
  class TestNode(BaseNode):
74
74
  foo = Inputs.foo
75
75
  bar = State.bar
@@ -10,7 +10,7 @@ import pydash
10
10
  import pytz
11
11
  import yaml
12
12
 
13
- from vellum.workflows.errors import VellumErrorCode
13
+ from vellum.workflows.errors import WorkflowErrorCode
14
14
  from vellum.workflows.exceptions import NodeException
15
15
  from vellum.workflows.nodes.bases import BaseNode
16
16
  from vellum.workflows.nodes.bases.base import BaseNodeMeta
@@ -130,4 +130,4 @@ class TemplatingNode(BaseNode[StateType], Generic[StateType, _OutputType], metac
130
130
  jinja_globals=self.jinja_globals,
131
131
  )
132
132
  except JinjaTemplateError as e:
133
- raise NodeException(message=str(e), code=VellumErrorCode.INVALID_TEMPLATE)
133
+ raise NodeException(message=str(e), code=WorkflowErrorCode.INVALID_TEMPLATE)
@@ -2,7 +2,7 @@ import sys
2
2
  from types import ModuleType
3
3
  from typing import TYPE_CHECKING, Any, Callable, Dict, Generic, Iterator, Optional, Set, Tuple, Type, TypeVar
4
4
 
5
- from vellum.workflows.errors.types import VellumError, VellumErrorCode
5
+ from vellum.workflows.errors.types import WorkflowError, WorkflowErrorCode
6
6
  from vellum.workflows.exceptions import NodeException
7
7
  from vellum.workflows.nodes.bases import BaseNode
8
8
  from vellum.workflows.nodes.bases.base import BaseNodeMeta
@@ -64,11 +64,11 @@ class TryNode(BaseNode[StateType], Generic[StateType], metaclass=_TryNodeMeta):
64
64
  """
65
65
 
66
66
  __wrapped_node__: Optional[Type["BaseNode"]] = None
67
- on_error_code: Optional[VellumErrorCode] = None
67
+ on_error_code: Optional[WorkflowErrorCode] = None
68
68
  subworkflow: Type["BaseWorkflow"]
69
69
 
70
70
  class Outputs(BaseNode.Outputs):
71
- error: Optional[VellumError] = None
71
+ error: Optional[WorkflowError] = None
72
72
 
73
73
  def run(self) -> Iterator[BaseOutput]:
74
74
  subworkflow = self.subworkflow(
@@ -98,13 +98,13 @@ class TryNode(BaseNode[StateType], Generic[StateType], metaclass=_TryNodeMeta):
98
98
  outputs = event.outputs
99
99
  elif event.name == "workflow.execution.paused":
100
100
  exception = NodeException(
101
- code=VellumErrorCode.INVALID_OUTPUTS,
101
+ code=WorkflowErrorCode.INVALID_OUTPUTS,
102
102
  message="Subworkflow unexpectedly paused within Try Node",
103
103
  )
104
104
  elif event.name == "workflow.execution.rejected":
105
105
  if self.on_error_code and self.on_error_code != event.error.code:
106
106
  exception = NodeException(
107
- code=VellumErrorCode.INVALID_OUTPUTS,
107
+ code=WorkflowErrorCode.INVALID_OUTPUTS,
108
108
  message=f"""Unexpected rejection: {event.error.code.value}.
109
109
  Message: {event.error.message}""",
110
110
  )
@@ -116,7 +116,7 @@ Message: {event.error.message}""",
116
116
 
117
117
  if outputs is None:
118
118
  raise NodeException(
119
- code=VellumErrorCode.INVALID_OUTPUTS,
119
+ code=WorkflowErrorCode.INVALID_OUTPUTS,
120
120
  message="Expected to receive outputs from Try Node's subworkflow",
121
121
  )
122
122
 
@@ -130,7 +130,7 @@ Message: {event.error.message}""",
130
130
  )
131
131
 
132
132
  @classmethod
133
- def wrap(cls, on_error_code: Optional[VellumErrorCode] = None) -> Callable[..., Type["TryNode"]]:
133
+ def wrap(cls, on_error_code: Optional[WorkflowErrorCode] = None) -> Callable[..., Type["TryNode"]]:
134
134
  _on_error_code = on_error_code
135
135
 
136
136
  def decorator(inner_cls: Type[BaseNode]) -> Type["TryNode"]:
@@ -1,7 +1,7 @@
1
1
  import pytest
2
2
 
3
3
  from vellum.client import Vellum
4
- from vellum.workflows.errors.types import VellumError, VellumErrorCode
4
+ from vellum.workflows.errors.types import WorkflowError, WorkflowErrorCode
5
5
  from vellum.workflows.exceptions import NodeException
6
6
  from vellum.workflows.inputs.base import BaseInputs
7
7
  from vellum.workflows.nodes.bases import BaseNode
@@ -14,13 +14,13 @@ from vellum.workflows.state.context import WorkflowContext
14
14
 
15
15
  def test_try_node__on_error_code__successfully_caught():
16
16
  # GIVEN a try node that is configured to catch PROVIDER_ERROR
17
- @TryNode.wrap(on_error_code=VellumErrorCode.PROVIDER_ERROR)
17
+ @TryNode.wrap(on_error_code=WorkflowErrorCode.PROVIDER_ERROR)
18
18
  class TestNode(BaseNode):
19
19
  class Outputs(BaseOutputs):
20
20
  value: int
21
21
 
22
22
  def run(self) -> Outputs:
23
- raise NodeException(message="This will be caught", code=VellumErrorCode.PROVIDER_ERROR)
23
+ raise NodeException(message="This will be caught", code=WorkflowErrorCode.PROVIDER_ERROR)
24
24
 
25
25
  # WHEN the node is run and throws a PROVIDER_ERROR
26
26
  node = TestNode(state=BaseState())
@@ -30,19 +30,21 @@ def test_try_node__on_error_code__successfully_caught():
30
30
  assert len(outputs) == 2
31
31
  assert set(outputs) == {
32
32
  BaseOutput(name="value"),
33
- BaseOutput(name="error", value=VellumError(message="This will be caught", code=VellumErrorCode.PROVIDER_ERROR)),
33
+ BaseOutput(
34
+ name="error", value=WorkflowError(message="This will be caught", code=WorkflowErrorCode.PROVIDER_ERROR)
35
+ ),
34
36
  }
35
37
 
36
38
 
37
39
  def test_try_node__retry_on_error_code__missed():
38
40
  # GIVEN a try node that is configured to catch PROVIDER_ERROR
39
- @TryNode.wrap(on_error_code=VellumErrorCode.PROVIDER_ERROR)
41
+ @TryNode.wrap(on_error_code=WorkflowErrorCode.PROVIDER_ERROR)
40
42
  class TestNode(BaseNode):
41
43
  class Outputs(BaseOutputs):
42
44
  value: int
43
45
 
44
46
  def run(self) -> Outputs:
45
- raise NodeException(message="This will be missed", code=VellumErrorCode.INTERNAL_ERROR)
47
+ raise NodeException(message="This will be missed", code=WorkflowErrorCode.INTERNAL_ERROR)
46
48
 
47
49
  # WHEN the node is run and throws a different exception
48
50
  node = TestNode(state=BaseState())
@@ -51,7 +53,7 @@ def test_try_node__retry_on_error_code__missed():
51
53
 
52
54
  # THEN the exception is not caught
53
55
  assert exc_info.value.message == "Unexpected rejection: INTERNAL_ERROR.\nMessage: This will be missed"
54
- assert exc_info.value.code == VellumErrorCode.INVALID_OUTPUTS
56
+ assert exc_info.value.code == WorkflowErrorCode.INVALID_OUTPUTS
55
57
 
56
58
 
57
59
  def test_try_node__use_parent_inputs_and_state():
@@ -4,7 +4,7 @@ from requests import Request, RequestException, Session
4
4
  from requests.exceptions import JSONDecodeError
5
5
 
6
6
  from vellum.workflows.constants import APIRequestMethod
7
- from vellum.workflows.errors.types import VellumErrorCode
7
+ from vellum.workflows.errors.types import WorkflowErrorCode
8
8
  from vellum.workflows.exceptions import NodeException
9
9
  from vellum.workflows.nodes.bases import BaseNode
10
10
  from vellum.workflows.outputs import BaseOutputs
@@ -49,13 +49,13 @@ class BaseAPINode(BaseNode, Generic[StateType]):
49
49
  try:
50
50
  prepped = Request(method=method.value, url=url, data=data, json=json, headers=headers).prepare()
51
51
  except Exception as e:
52
- raise NodeException(f"Failed to prepare HTTP request: {e}", code=VellumErrorCode.PROVIDER_ERROR)
52
+ raise NodeException(f"Failed to prepare HTTP request: {e}", code=WorkflowErrorCode.PROVIDER_ERROR)
53
53
 
54
54
  try:
55
55
  with Session() as session:
56
56
  response = session.send(prepped)
57
57
  except RequestException as e:
58
- raise NodeException(f"HTTP request failed: {e}", code=VellumErrorCode.PROVIDER_ERROR)
58
+ raise NodeException(f"HTTP request failed: {e}", code=WorkflowErrorCode.PROVIDER_ERROR)
59
59
 
60
60
  try:
61
61
  json = response.json()