vellum-ai 0.11.9__py3-none-any.whl → 0.12.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) 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 +21 -5
  26. vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +141 -0
  27. vellum/workflows/nodes/displayable/guardrail_node/node.py +3 -3
  28. vellum/workflows/nodes/displayable/inline_prompt_node/node.py +3 -3
  29. vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +3 -3
  30. vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +7 -14
  31. vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py +4 -4
  32. vellum/workflows/nodes/utils.py +5 -9
  33. vellum/workflows/references/external_input.py +2 -2
  34. vellum/workflows/references/node.py +2 -2
  35. vellum/workflows/references/state_value.py +2 -2
  36. vellum/workflows/references/workflow_input.py +2 -2
  37. vellum/workflows/runner/runner.py +15 -15
  38. {vellum_ee/workflows/display → vellum/workflows}/utils/tests/test_uuids.py +1 -1
  39. vellum/workflows/workflows/base.py +7 -7
  40. {vellum_ai-0.11.9.dist-info → vellum_ai-0.12.0.dist-info}/METADATA +1 -1
  41. {vellum_ai-0.11.9.dist-info → vellum_ai-0.12.0.dist-info}/RECORD +61 -62
  42. {vellum_ai-0.11.9.dist-info → vellum_ai-0.12.0.dist-info}/WHEEL +1 -1
  43. vellum_ee/workflows/display/nodes/base_node_display.py +50 -21
  44. vellum_ee/workflows/display/nodes/base_node_vellum_display.py +10 -1
  45. vellum_ee/workflows/display/nodes/get_node_display_class.py +10 -1
  46. vellum_ee/workflows/display/nodes/tests/test_base_node_display.py +5 -4
  47. vellum_ee/workflows/display/nodes/vellum/code_execution_node.py +13 -3
  48. vellum_ee/workflows/display/nodes/vellum/conditional_node.py +1 -1
  49. vellum_ee/workflows/display/nodes/vellum/final_output_node.py +1 -1
  50. vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +1 -1
  51. vellum_ee/workflows/display/nodes/vellum/merge_node.py +4 -4
  52. vellum_ee/workflows/display/nodes/vellum/search_node.py +1 -1
  53. vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +5 -1
  54. vellum_ee/workflows/display/nodes/vellum/try_node.py +12 -6
  55. vellum_ee/workflows/display/nodes/vellum/utils.py +1 -1
  56. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +269 -85
  57. vellum_ee/workflows/display/workflows/base_workflow_display.py +2 -2
  58. vellum_ee/workflows/display/workflows/vellum_workflow_display.py +2 -6
  59. vellum_ee/workflows/display/utils/tests/__init__.py +0 -0
  60. {vellum_ee/workflows/display → vellum/workflows}/utils/uuids.py +0 -0
  61. {vellum_ai-0.11.9.dist-info → vellum_ai-0.12.0.dist-info}/LICENSE +0 -0
  62. {vellum_ai-0.11.9.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.9",
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()