vellum-ai 0.9.16rc2__py3-none-any.whl → 0.9.16rc4__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (245) hide show
  1. vellum/plugins/__init__.py +0 -0
  2. vellum/plugins/pydantic.py +74 -0
  3. vellum/plugins/utils.py +19 -0
  4. vellum/plugins/vellum_mypy.py +639 -3
  5. vellum/workflows/README.md +90 -0
  6. vellum/workflows/__init__.py +5 -0
  7. vellum/workflows/constants.py +43 -0
  8. vellum/workflows/descriptors/__init__.py +0 -0
  9. vellum/workflows/descriptors/base.py +339 -0
  10. vellum/workflows/descriptors/tests/test_utils.py +83 -0
  11. vellum/workflows/descriptors/utils.py +90 -0
  12. vellum/workflows/edges/__init__.py +5 -0
  13. vellum/workflows/edges/edge.py +23 -0
  14. vellum/workflows/emitters/__init__.py +5 -0
  15. vellum/workflows/emitters/base.py +14 -0
  16. vellum/workflows/environment/__init__.py +5 -0
  17. vellum/workflows/environment/environment.py +7 -0
  18. vellum/workflows/errors/__init__.py +6 -0
  19. vellum/workflows/errors/types.py +20 -0
  20. vellum/workflows/events/__init__.py +31 -0
  21. vellum/workflows/events/node.py +125 -0
  22. vellum/workflows/events/tests/__init__.py +0 -0
  23. vellum/workflows/events/tests/test_event.py +216 -0
  24. vellum/workflows/events/types.py +52 -0
  25. vellum/workflows/events/utils.py +5 -0
  26. vellum/workflows/events/workflow.py +139 -0
  27. vellum/workflows/exceptions.py +15 -0
  28. vellum/workflows/expressions/__init__.py +0 -0
  29. vellum/workflows/expressions/accessor.py +52 -0
  30. vellum/workflows/expressions/and_.py +32 -0
  31. vellum/workflows/expressions/begins_with.py +31 -0
  32. vellum/workflows/expressions/between.py +38 -0
  33. vellum/workflows/expressions/coalesce_expression.py +41 -0
  34. vellum/workflows/expressions/contains.py +30 -0
  35. vellum/workflows/expressions/does_not_begin_with.py +31 -0
  36. vellum/workflows/expressions/does_not_contain.py +30 -0
  37. vellum/workflows/expressions/does_not_end_with.py +31 -0
  38. vellum/workflows/expressions/does_not_equal.py +25 -0
  39. vellum/workflows/expressions/ends_with.py +31 -0
  40. vellum/workflows/expressions/equals.py +25 -0
  41. vellum/workflows/expressions/greater_than.py +33 -0
  42. vellum/workflows/expressions/greater_than_or_equal_to.py +33 -0
  43. vellum/workflows/expressions/in_.py +31 -0
  44. vellum/workflows/expressions/is_blank.py +24 -0
  45. vellum/workflows/expressions/is_not_blank.py +24 -0
  46. vellum/workflows/expressions/is_not_null.py +21 -0
  47. vellum/workflows/expressions/is_not_undefined.py +22 -0
  48. vellum/workflows/expressions/is_null.py +21 -0
  49. vellum/workflows/expressions/is_undefined.py +22 -0
  50. vellum/workflows/expressions/less_than.py +33 -0
  51. vellum/workflows/expressions/less_than_or_equal_to.py +33 -0
  52. vellum/workflows/expressions/not_between.py +38 -0
  53. vellum/workflows/expressions/not_in.py +31 -0
  54. vellum/workflows/expressions/or_.py +32 -0
  55. vellum/workflows/graph/__init__.py +3 -0
  56. vellum/workflows/graph/graph.py +131 -0
  57. vellum/workflows/graph/tests/__init__.py +0 -0
  58. vellum/workflows/graph/tests/test_graph.py +437 -0
  59. vellum/workflows/inputs/__init__.py +5 -0
  60. vellum/workflows/inputs/base.py +55 -0
  61. vellum/workflows/logging.py +14 -0
  62. vellum/workflows/nodes/__init__.py +46 -0
  63. vellum/workflows/nodes/bases/__init__.py +7 -0
  64. vellum/workflows/nodes/bases/base.py +332 -0
  65. vellum/workflows/nodes/bases/base_subworkflow_node/__init__.py +5 -0
  66. vellum/workflows/nodes/bases/base_subworkflow_node/node.py +10 -0
  67. vellum/workflows/nodes/bases/tests/__init__.py +0 -0
  68. vellum/workflows/nodes/bases/tests/test_base_node.py +125 -0
  69. vellum/workflows/nodes/core/__init__.py +16 -0
  70. vellum/workflows/nodes/core/error_node/__init__.py +5 -0
  71. vellum/workflows/nodes/core/error_node/node.py +26 -0
  72. vellum/workflows/nodes/core/inline_subworkflow_node/__init__.py +5 -0
  73. vellum/workflows/nodes/core/inline_subworkflow_node/node.py +73 -0
  74. vellum/workflows/nodes/core/map_node/__init__.py +5 -0
  75. vellum/workflows/nodes/core/map_node/node.py +147 -0
  76. vellum/workflows/nodes/core/map_node/tests/__init__.py +0 -0
  77. vellum/workflows/nodes/core/map_node/tests/test_node.py +65 -0
  78. vellum/workflows/nodes/core/retry_node/__init__.py +5 -0
  79. vellum/workflows/nodes/core/retry_node/node.py +106 -0
  80. vellum/workflows/nodes/core/retry_node/tests/__init__.py +0 -0
  81. vellum/workflows/nodes/core/retry_node/tests/test_node.py +93 -0
  82. vellum/workflows/nodes/core/templating_node/__init__.py +5 -0
  83. vellum/workflows/nodes/core/templating_node/custom_filters.py +12 -0
  84. vellum/workflows/nodes/core/templating_node/exceptions.py +2 -0
  85. vellum/workflows/nodes/core/templating_node/node.py +123 -0
  86. vellum/workflows/nodes/core/templating_node/render.py +55 -0
  87. vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py +21 -0
  88. vellum/workflows/nodes/core/try_node/__init__.py +5 -0
  89. vellum/workflows/nodes/core/try_node/node.py +110 -0
  90. vellum/workflows/nodes/core/try_node/tests/__init__.py +0 -0
  91. vellum/workflows/nodes/core/try_node/tests/test_node.py +82 -0
  92. vellum/workflows/nodes/displayable/__init__.py +31 -0
  93. vellum/workflows/nodes/displayable/api_node/__init__.py +5 -0
  94. vellum/workflows/nodes/displayable/api_node/node.py +44 -0
  95. vellum/workflows/nodes/displayable/bases/__init__.py +11 -0
  96. vellum/workflows/nodes/displayable/bases/api_node/__init__.py +5 -0
  97. vellum/workflows/nodes/displayable/bases/api_node/node.py +70 -0
  98. vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py +5 -0
  99. vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +60 -0
  100. vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py +5 -0
  101. vellum/workflows/nodes/displayable/bases/inline_prompt_node/constants.py +13 -0
  102. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +118 -0
  103. vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +98 -0
  104. vellum/workflows/nodes/displayable/bases/search_node.py +90 -0
  105. vellum/workflows/nodes/displayable/code_execution_node/__init__.py +5 -0
  106. vellum/workflows/nodes/displayable/code_execution_node/node.py +197 -0
  107. vellum/workflows/nodes/displayable/code_execution_node/tests/__init__.py +0 -0
  108. vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/__init__.py +0 -0
  109. vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/main.py +3 -0
  110. vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +111 -0
  111. vellum/workflows/nodes/displayable/code_execution_node/utils.py +10 -0
  112. vellum/workflows/nodes/displayable/conditional_node/__init__.py +5 -0
  113. vellum/workflows/nodes/displayable/conditional_node/node.py +25 -0
  114. vellum/workflows/nodes/displayable/final_output_node/__init__.py +5 -0
  115. vellum/workflows/nodes/displayable/final_output_node/node.py +43 -0
  116. vellum/workflows/nodes/displayable/guardrail_node/__init__.py +5 -0
  117. vellum/workflows/nodes/displayable/guardrail_node/node.py +97 -0
  118. vellum/workflows/nodes/displayable/inline_prompt_node/__init__.py +5 -0
  119. vellum/workflows/nodes/displayable/inline_prompt_node/node.py +41 -0
  120. vellum/workflows/nodes/displayable/merge_node/__init__.py +5 -0
  121. vellum/workflows/nodes/displayable/merge_node/node.py +10 -0
  122. vellum/workflows/nodes/displayable/prompt_deployment_node/__init__.py +5 -0
  123. vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +45 -0
  124. vellum/workflows/nodes/displayable/search_node/__init__.py +5 -0
  125. vellum/workflows/nodes/displayable/search_node/node.py +26 -0
  126. vellum/workflows/nodes/displayable/subworkflow_deployment_node/__init__.py +5 -0
  127. vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +156 -0
  128. vellum/workflows/nodes/displayable/tests/__init__.py +0 -0
  129. vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py +148 -0
  130. vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py +134 -0
  131. vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +80 -0
  132. vellum/workflows/nodes/utils.py +27 -0
  133. vellum/workflows/outputs/__init__.py +6 -0
  134. vellum/workflows/outputs/base.py +196 -0
  135. vellum/workflows/ports/__init__.py +7 -0
  136. vellum/workflows/ports/node_ports.py +75 -0
  137. vellum/workflows/ports/port.py +75 -0
  138. vellum/workflows/ports/utils.py +40 -0
  139. vellum/workflows/references/__init__.py +17 -0
  140. vellum/workflows/references/environment_variable.py +20 -0
  141. vellum/workflows/references/execution_count.py +20 -0
  142. vellum/workflows/references/external_input.py +49 -0
  143. vellum/workflows/references/input.py +7 -0
  144. vellum/workflows/references/lazy.py +55 -0
  145. vellum/workflows/references/node.py +43 -0
  146. vellum/workflows/references/output.py +78 -0
  147. vellum/workflows/references/state_value.py +23 -0
  148. vellum/workflows/references/vellum_secret.py +15 -0
  149. vellum/workflows/references/workflow_input.py +41 -0
  150. vellum/workflows/resolvers/__init__.py +5 -0
  151. vellum/workflows/resolvers/base.py +15 -0
  152. vellum/workflows/runner/__init__.py +5 -0
  153. vellum/workflows/runner/runner.py +588 -0
  154. vellum/workflows/runner/types.py +18 -0
  155. vellum/workflows/state/__init__.py +5 -0
  156. vellum/workflows/state/base.py +327 -0
  157. vellum/workflows/state/context.py +18 -0
  158. vellum/workflows/state/encoder.py +57 -0
  159. vellum/workflows/state/store.py +28 -0
  160. vellum/workflows/state/tests/__init__.py +0 -0
  161. vellum/workflows/state/tests/test_state.py +113 -0
  162. vellum/workflows/types/__init__.py +0 -0
  163. vellum/workflows/types/core.py +91 -0
  164. vellum/workflows/types/generics.py +14 -0
  165. vellum/workflows/types/stack.py +39 -0
  166. vellum/workflows/types/tests/__init__.py +0 -0
  167. vellum/workflows/types/tests/test_utils.py +76 -0
  168. vellum/workflows/types/utils.py +164 -0
  169. vellum/workflows/utils/__init__.py +0 -0
  170. vellum/workflows/utils/names.py +13 -0
  171. vellum/workflows/utils/tests/__init__.py +0 -0
  172. vellum/workflows/utils/tests/test_names.py +15 -0
  173. vellum/workflows/utils/tests/test_vellum_variables.py +25 -0
  174. vellum/workflows/utils/vellum_variables.py +81 -0
  175. vellum/workflows/vellum_client.py +18 -0
  176. vellum/workflows/workflows/__init__.py +5 -0
  177. vellum/workflows/workflows/base.py +365 -0
  178. {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.dist-info}/METADATA +2 -1
  179. {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.dist-info}/RECORD +245 -7
  180. vellum_cli/__init__.py +72 -0
  181. vellum_cli/aliased_group.py +103 -0
  182. vellum_cli/config.py +96 -0
  183. vellum_cli/image_push.py +112 -0
  184. vellum_cli/logger.py +36 -0
  185. vellum_cli/pull.py +73 -0
  186. vellum_cli/push.py +121 -0
  187. vellum_cli/tests/test_config.py +100 -0
  188. vellum_cli/tests/test_pull.py +152 -0
  189. vellum_ee/workflows/__init__.py +0 -0
  190. vellum_ee/workflows/display/__init__.py +0 -0
  191. vellum_ee/workflows/display/base.py +73 -0
  192. vellum_ee/workflows/display/nodes/__init__.py +4 -0
  193. vellum_ee/workflows/display/nodes/base_node_display.py +116 -0
  194. vellum_ee/workflows/display/nodes/base_node_vellum_display.py +36 -0
  195. vellum_ee/workflows/display/nodes/get_node_display_class.py +25 -0
  196. vellum_ee/workflows/display/nodes/tests/__init__.py +0 -0
  197. vellum_ee/workflows/display/nodes/tests/test_base_node_display.py +47 -0
  198. vellum_ee/workflows/display/nodes/types.py +18 -0
  199. vellum_ee/workflows/display/nodes/utils.py +33 -0
  200. vellum_ee/workflows/display/nodes/vellum/__init__.py +32 -0
  201. vellum_ee/workflows/display/nodes/vellum/api_node.py +205 -0
  202. vellum_ee/workflows/display/nodes/vellum/code_execution_node.py +71 -0
  203. vellum_ee/workflows/display/nodes/vellum/conditional_node.py +217 -0
  204. vellum_ee/workflows/display/nodes/vellum/final_output_node.py +61 -0
  205. vellum_ee/workflows/display/nodes/vellum/guardrail_node.py +49 -0
  206. vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +170 -0
  207. vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py +99 -0
  208. vellum_ee/workflows/display/nodes/vellum/map_node.py +100 -0
  209. vellum_ee/workflows/display/nodes/vellum/merge_node.py +48 -0
  210. vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +68 -0
  211. vellum_ee/workflows/display/nodes/vellum/search_node.py +193 -0
  212. vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py +58 -0
  213. vellum_ee/workflows/display/nodes/vellum/templating_node.py +67 -0
  214. vellum_ee/workflows/display/nodes/vellum/tests/__init__.py +0 -0
  215. vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +106 -0
  216. vellum_ee/workflows/display/nodes/vellum/try_node.py +38 -0
  217. vellum_ee/workflows/display/nodes/vellum/utils.py +76 -0
  218. vellum_ee/workflows/display/tests/__init__.py +0 -0
  219. vellum_ee/workflows/display/tests/workflow_serialization/__init__.py +0 -0
  220. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +426 -0
  221. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +607 -0
  222. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +1175 -0
  223. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_guardrail_node_serialization.py +235 -0
  224. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +511 -0
  225. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +372 -0
  226. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +272 -0
  227. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_prompt_deployment_serialization.py +289 -0
  228. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_deployment_serialization.py +354 -0
  229. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py +123 -0
  230. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py +84 -0
  231. vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py +233 -0
  232. vellum_ee/workflows/display/types.py +46 -0
  233. vellum_ee/workflows/display/utils/__init__.py +0 -0
  234. vellum_ee/workflows/display/utils/tests/__init__.py +0 -0
  235. vellum_ee/workflows/display/utils/tests/test_uuids.py +16 -0
  236. vellum_ee/workflows/display/utils/uuids.py +24 -0
  237. vellum_ee/workflows/display/utils/vellum.py +121 -0
  238. vellum_ee/workflows/display/vellum.py +357 -0
  239. vellum_ee/workflows/display/workflows/__init__.py +5 -0
  240. vellum_ee/workflows/display/workflows/base_workflow_display.py +302 -0
  241. vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py +32 -0
  242. vellum_ee/workflows/display/workflows/vellum_workflow_display.py +386 -0
  243. {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.dist-info}/LICENSE +0 -0
  244. {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.dist-info}/WHEEL +0 -0
  245. {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,5 @@
1
+ from .base import BaseWorkflowEmitter
2
+
3
+ __all__ = [
4
+ "BaseWorkflowEmitter",
5
+ ]
@@ -0,0 +1,14 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from vellum.workflows.events.workflow import WorkflowEvent
4
+ from vellum.workflows.state.base import BaseState
5
+
6
+
7
+ class BaseWorkflowEmitter(ABC):
8
+ @abstractmethod
9
+ def emit_event(self, event: WorkflowEvent) -> None:
10
+ pass
11
+
12
+ @abstractmethod
13
+ def snapshot_state(self, state: BaseState) -> None:
14
+ pass
@@ -0,0 +1,5 @@
1
+ from .environment import Environment
2
+
3
+ __all__ = [
4
+ "Environment",
5
+ ]
@@ -0,0 +1,7 @@
1
+ from vellum.workflows.references import EnvironmentVariableReference
2
+
3
+
4
+ class Environment:
5
+ @staticmethod
6
+ def get(name: str) -> EnvironmentVariableReference:
7
+ return EnvironmentVariableReference(name=name)
@@ -0,0 +1,6 @@
1
+ from .types import VellumError, VellumErrorCode
2
+
3
+ __all__ = [
4
+ "VellumError",
5
+ "VellumErrorCode",
6
+ ]
@@ -0,0 +1,20 @@
1
+ from dataclasses import dataclass
2
+ from enum import Enum
3
+
4
+
5
+ class VellumErrorCode(Enum):
6
+ INVALID_WORKFLOW = "INVALID_WORKFLOW"
7
+ INVALID_INPUTS = "INVALID_INPUTS"
8
+ INVALID_OUTPUTS = "INVALID_OUTPUTS"
9
+ INVALID_STATE = "INVALID_STATE"
10
+ INVALID_TEMPLATE = "INVALID_TEMPLATE"
11
+ INTERNAL_ERROR = "INTERNAL_ERROR"
12
+ PROVIDER_ERROR = "PROVIDER_ERROR"
13
+ USER_DEFINED_ERROR = "USER_DEFINED_ERROR"
14
+ WORKFLOW_CANCELLED = "WORKFLOW_CANCELLED"
15
+
16
+
17
+ @dataclass(frozen=True)
18
+ class VellumError:
19
+ message: str
20
+ code: VellumErrorCode
@@ -0,0 +1,31 @@
1
+ from .node import (
2
+ NodeEvent,
3
+ NodeExecutionFulfilledEvent,
4
+ NodeExecutionInitiatedEvent,
5
+ NodeExecutionRejectedEvent,
6
+ NodeExecutionStreamingEvent,
7
+ )
8
+ from .types import WorkflowEventType
9
+ from .workflow import (
10
+ WorkflowEvent,
11
+ WorkflowEventStream,
12
+ WorkflowExecutionFulfilledEvent,
13
+ WorkflowExecutionInitiatedEvent,
14
+ WorkflowExecutionRejectedEvent,
15
+ WorkflowExecutionStreamingEvent,
16
+ )
17
+
18
+ __all__ = [
19
+ "NodeExecutionFulfilledEvent",
20
+ "WorkflowExecutionFulfilledEvent",
21
+ "NodeExecutionInitiatedEvent",
22
+ "WorkflowExecutionInitiatedEvent",
23
+ "NodeEvent",
24
+ "NodeExecutionRejectedEvent",
25
+ "WorkflowExecutionRejectedEvent",
26
+ "NodeExecutionStreamingEvent",
27
+ "WorkflowExecutionStreamingEvent",
28
+ "WorkflowEvent",
29
+ "WorkflowEventStream",
30
+ "WorkflowEventType",
31
+ ]
@@ -0,0 +1,125 @@
1
+ from typing import Any, Dict, Generic, Literal, Type, Union
2
+
3
+ from pydantic import field_serializer
4
+
5
+ from vellum.core.pydantic_utilities import UniversalBaseModel
6
+
7
+ from vellum.workflows.errors import VellumError
8
+ from vellum.workflows.expressions.accessor import AccessorExpression
9
+ from vellum.workflows.nodes.bases import BaseNode
10
+ from vellum.workflows.outputs.base import BaseOutput
11
+ from vellum.workflows.references.node import NodeReference
12
+ from vellum.workflows.types.generics import OutputsType
13
+
14
+ from .types import BaseEvent, default_serializer, serialize_type_encoder
15
+
16
+
17
+ class _BaseNodeExecutionBody(UniversalBaseModel):
18
+ node_definition: Type[BaseNode]
19
+
20
+ @field_serializer("node_definition")
21
+ def serialize_node_definition(self, node_definition: Type, _info: Any) -> Dict[str, Any]:
22
+ return serialize_type_encoder(node_definition)
23
+
24
+
25
+ class _BaseNodeEvent(BaseEvent):
26
+ body: _BaseNodeExecutionBody
27
+
28
+ @property
29
+ def node_definition(self) -> Type[BaseNode]:
30
+ return self.body.node_definition
31
+
32
+
33
+ NodeInputName = Union[NodeReference, AccessorExpression]
34
+
35
+
36
+ class NodeExecutionInitiatedBody(_BaseNodeExecutionBody):
37
+ inputs: Dict[NodeInputName, Any]
38
+
39
+ @field_serializer("inputs")
40
+ def serialize_inputs(self, inputs: Dict[NodeInputName, Any], _info: Any) -> Dict[str, Any]:
41
+ return default_serializer({descriptor.name: value for descriptor, value in inputs.items()})
42
+
43
+
44
+ class NodeExecutionInitiatedEvent(_BaseNodeEvent):
45
+ name: Literal["node.execution.initiated"] = "node.execution.initiated"
46
+ body: NodeExecutionInitiatedBody
47
+
48
+ @property
49
+ def inputs(self) -> Dict[NodeInputName, Any]:
50
+ return self.body.inputs
51
+
52
+
53
+ class NodeExecutionStreamingBody(_BaseNodeExecutionBody):
54
+ output: BaseOutput
55
+
56
+ @field_serializer("output")
57
+ def serialize_output(self, output: BaseOutput, _info: Any) -> Dict[str, Any]:
58
+ return default_serializer(output)
59
+
60
+
61
+ class NodeExecutionStreamingEvent(_BaseNodeEvent):
62
+ name: Literal["node.execution.streaming"] = "node.execution.streaming"
63
+ body: NodeExecutionStreamingBody
64
+
65
+ @property
66
+ def output(self) -> BaseOutput:
67
+ return self.body.output
68
+
69
+
70
+ class NodeExecutionFulfilledBody(_BaseNodeExecutionBody, Generic[OutputsType]):
71
+ outputs: OutputsType
72
+
73
+ @field_serializer("outputs")
74
+ def serialize_outputs(self, outputs: OutputsType, _info: Any) -> Dict[str, Any]:
75
+ return default_serializer(outputs)
76
+
77
+
78
+ class NodeExecutionFulfilledEvent(_BaseNodeEvent, Generic[OutputsType]):
79
+ name: Literal["node.execution.fulfilled"] = "node.execution.fulfilled"
80
+ body: NodeExecutionFulfilledBody[OutputsType]
81
+
82
+ @property
83
+ def outputs(self) -> OutputsType:
84
+ return self.body.outputs
85
+
86
+
87
+ class NodeExecutionRejectedBody(_BaseNodeExecutionBody):
88
+ error: VellumError
89
+
90
+
91
+ class NodeExecutionRejectedEvent(_BaseNodeEvent):
92
+ name: Literal["node.execution.rejected"] = "node.execution.rejected"
93
+ body: NodeExecutionRejectedBody
94
+
95
+ @property
96
+ def error(self) -> VellumError:
97
+ return self.body.error
98
+
99
+
100
+ class NodeExecutionPausedBody(_BaseNodeExecutionBody):
101
+ pass
102
+
103
+
104
+ class NodeExecutionPausedEvent(_BaseNodeEvent):
105
+ name: Literal["node.execution.paused"] = "node.execution.paused"
106
+ body: NodeExecutionPausedBody
107
+
108
+
109
+ class NodeExecutionResumedBody(_BaseNodeExecutionBody):
110
+ pass
111
+
112
+
113
+ class NodeExecutionResumedEvent(_BaseNodeEvent):
114
+ name: Literal["node.execution.resumed"] = "node.execution.resumed"
115
+ body: NodeExecutionResumedBody
116
+
117
+
118
+ NodeEvent = Union[
119
+ NodeExecutionInitiatedEvent,
120
+ NodeExecutionStreamingEvent,
121
+ NodeExecutionFulfilledEvent,
122
+ NodeExecutionRejectedEvent,
123
+ NodeExecutionPausedEvent,
124
+ NodeExecutionResumedEvent,
125
+ ]
File without changes
@@ -0,0 +1,216 @@
1
+ import pytest
2
+ from datetime import datetime
3
+ import json
4
+ from uuid import UUID
5
+
6
+ from deepdiff import DeepDiff
7
+
8
+ from vellum.workflows.errors.types import VellumError, VellumErrorCode
9
+ from vellum.workflows.events.node import NodeExecutionInitiatedBody, NodeExecutionInitiatedEvent
10
+ from vellum.workflows.events.workflow import (
11
+ WorkflowExecutionFulfilledBody,
12
+ WorkflowExecutionFulfilledEvent,
13
+ WorkflowExecutionInitiatedBody,
14
+ WorkflowExecutionInitiatedEvent,
15
+ WorkflowExecutionRejectedBody,
16
+ WorkflowExecutionRejectedEvent,
17
+ WorkflowExecutionStreamingBody,
18
+ WorkflowExecutionStreamingEvent,
19
+ )
20
+ from vellum.workflows.inputs.base import BaseInputs
21
+ from vellum.workflows.nodes.bases.base import BaseNode
22
+ from vellum.workflows.outputs.base import BaseOutput
23
+ from vellum.workflows.state.base import BaseState
24
+ from vellum.workflows.workflows.base import BaseWorkflow
25
+
26
+
27
+ class MockInputs(BaseInputs):
28
+ foo: str
29
+
30
+
31
+ class MockNode(BaseNode):
32
+ node_foo = MockInputs.foo
33
+
34
+ class Outputs(BaseNode.Outputs):
35
+ example: str
36
+
37
+
38
+ class MockWorkflow(BaseWorkflow[MockInputs, BaseState]):
39
+ graph = MockNode
40
+
41
+
42
+ name_parts = __name__.split(".")
43
+ module_root = name_parts[: name_parts.index("events")]
44
+
45
+
46
+ @pytest.mark.parametrize(
47
+ ["event", "expected_json"],
48
+ [
49
+ (
50
+ WorkflowExecutionInitiatedEvent(
51
+ id=UUID("123e4567-e89b-12d3-a456-426614174000"),
52
+ timestamp=datetime(2024, 1, 1, 12, 0, 0),
53
+ trace_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
54
+ span_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
55
+ body=WorkflowExecutionInitiatedBody(
56
+ workflow_definition=MockWorkflow,
57
+ inputs=MockInputs(foo="bar"),
58
+ ),
59
+ ),
60
+ {
61
+ "id": "123e4567-e89b-12d3-a456-426614174000",
62
+ "api_version": "2024-10-25",
63
+ "timestamp": "2024-01-01T12:00:00",
64
+ "trace_id": "123e4567-e89b-12d3-a456-426614174000",
65
+ "span_id": "123e4567-e89b-12d3-a456-426614174000",
66
+ "name": "workflow.execution.initiated",
67
+ "body": {
68
+ "workflow_definition": {
69
+ "name": "MockWorkflow",
70
+ "module": module_root + ["events", "tests", "test_event"],
71
+ },
72
+ "inputs": {
73
+ "foo": "bar",
74
+ },
75
+ },
76
+ },
77
+ ),
78
+ (
79
+ NodeExecutionInitiatedEvent(
80
+ id=UUID("123e4567-e89b-12d3-a456-426614174000"),
81
+ timestamp=datetime(2024, 1, 1, 12, 0, 0),
82
+ trace_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
83
+ span_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
84
+ body=NodeExecutionInitiatedBody(
85
+ node_definition=MockNode,
86
+ inputs={
87
+ MockNode.node_foo: "bar",
88
+ },
89
+ ),
90
+ ),
91
+ {
92
+ "id": "123e4567-e89b-12d3-a456-426614174000",
93
+ "api_version": "2024-10-25",
94
+ "timestamp": "2024-01-01T12:00:00",
95
+ "trace_id": "123e4567-e89b-12d3-a456-426614174000",
96
+ "span_id": "123e4567-e89b-12d3-a456-426614174000",
97
+ "name": "node.execution.initiated",
98
+ "body": {
99
+ "node_definition": {
100
+ "name": "MockNode",
101
+ "module": module_root + ["events", "tests", "test_event"],
102
+ },
103
+ "inputs": {
104
+ "node_foo": "bar",
105
+ },
106
+ },
107
+ },
108
+ ),
109
+ (
110
+ WorkflowExecutionStreamingEvent(
111
+ id=UUID("123e4567-e89b-12d3-a456-426614174000"),
112
+ timestamp=datetime(2024, 1, 1, 12, 0, 0),
113
+ trace_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
114
+ span_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
115
+ body=WorkflowExecutionStreamingBody(
116
+ workflow_definition=MockWorkflow,
117
+ output=BaseOutput(
118
+ name="example",
119
+ value="foo",
120
+ ),
121
+ ),
122
+ ),
123
+ {
124
+ "id": "123e4567-e89b-12d3-a456-426614174000",
125
+ "api_version": "2024-10-25",
126
+ "timestamp": "2024-01-01T12:00:00",
127
+ "trace_id": "123e4567-e89b-12d3-a456-426614174000",
128
+ "span_id": "123e4567-e89b-12d3-a456-426614174000",
129
+ "name": "workflow.execution.streaming",
130
+ "body": {
131
+ "workflow_definition": {
132
+ "name": "MockWorkflow",
133
+ "module": module_root + ["events", "tests", "test_event"],
134
+ },
135
+ "output": {
136
+ "name": "example",
137
+ "value": "foo",
138
+ },
139
+ },
140
+ },
141
+ ),
142
+ (
143
+ WorkflowExecutionFulfilledEvent(
144
+ id=UUID("123e4567-e89b-12d3-a456-426614174000"),
145
+ timestamp=datetime(2024, 1, 1, 12, 0, 0),
146
+ trace_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
147
+ span_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
148
+ body=WorkflowExecutionFulfilledBody(
149
+ workflow_definition=MockWorkflow,
150
+ outputs=MockNode.Outputs(
151
+ example="foo",
152
+ ),
153
+ ),
154
+ ),
155
+ {
156
+ "id": "123e4567-e89b-12d3-a456-426614174000",
157
+ "api_version": "2024-10-25",
158
+ "timestamp": "2024-01-01T12:00:00",
159
+ "trace_id": "123e4567-e89b-12d3-a456-426614174000",
160
+ "span_id": "123e4567-e89b-12d3-a456-426614174000",
161
+ "name": "workflow.execution.fulfilled",
162
+ "body": {
163
+ "workflow_definition": {
164
+ "name": "MockWorkflow",
165
+ "module": module_root + ["events", "tests", "test_event"],
166
+ },
167
+ "outputs": {
168
+ "example": "foo",
169
+ },
170
+ },
171
+ },
172
+ ),
173
+ (
174
+ WorkflowExecutionRejectedEvent(
175
+ id=UUID("123e4567-e89b-12d3-a456-426614174000"),
176
+ timestamp=datetime(2024, 1, 1, 12, 0, 0),
177
+ trace_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
178
+ span_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
179
+ body=WorkflowExecutionRejectedBody(
180
+ workflow_definition=MockWorkflow,
181
+ error=VellumError(
182
+ message="Workflow failed",
183
+ code=VellumErrorCode.USER_DEFINED_ERROR,
184
+ ),
185
+ ),
186
+ ),
187
+ {
188
+ "id": "123e4567-e89b-12d3-a456-426614174000",
189
+ "api_version": "2024-10-25",
190
+ "timestamp": "2024-01-01T12:00:00",
191
+ "trace_id": "123e4567-e89b-12d3-a456-426614174000",
192
+ "span_id": "123e4567-e89b-12d3-a456-426614174000",
193
+ "name": "workflow.execution.rejected",
194
+ "body": {
195
+ "workflow_definition": {
196
+ "name": "MockWorkflow",
197
+ "module": module_root + ["events", "tests", "test_event"],
198
+ },
199
+ "error": {
200
+ "message": "Workflow failed",
201
+ "code": "USER_DEFINED_ERROR",
202
+ },
203
+ },
204
+ },
205
+ ),
206
+ ],
207
+ ids=[
208
+ "workflow.execution.initiated",
209
+ "node.execution.initiated",
210
+ "workflow.execution.streaming",
211
+ "workflow.execution.fulfilled",
212
+ "workflow.execution.rejected",
213
+ ],
214
+ )
215
+ def test_event_serialization(event, expected_json):
216
+ assert not DeepDiff(json.loads(event.model_dump_json()), expected_json)
@@ -0,0 +1,52 @@
1
+ from datetime import datetime
2
+ from enum import Enum
3
+ import json
4
+ from uuid import UUID, uuid4
5
+ from typing import Any, Dict, Literal
6
+
7
+ from pydantic import Field
8
+
9
+ from vellum.core.pydantic_utilities import UniversalBaseModel
10
+
11
+ from vellum.workflows.state.encoder import DefaultStateEncoder
12
+ from vellum.workflows.types.utils import datetime_now
13
+
14
+
15
+ class WorkflowEventType(Enum):
16
+ NODE = "NODE"
17
+ WORKFLOW = "WORKFLOW"
18
+
19
+
20
+ def default_datetime_factory() -> datetime:
21
+ """
22
+ Makes it possible to mock the datetime factory for testing.
23
+ """
24
+
25
+ return datetime_now()
26
+
27
+
28
+ excluded_modules = {"typing", "builtins"}
29
+
30
+
31
+ def serialize_type_encoder(obj: type) -> Dict[str, Any]:
32
+ return {
33
+ "name": obj.__name__,
34
+ "module": obj.__module__.split("."),
35
+ }
36
+
37
+
38
+ def default_serializer(obj: Any) -> Any:
39
+ return json.loads(
40
+ json.dumps(
41
+ obj,
42
+ cls=DefaultStateEncoder,
43
+ )
44
+ )
45
+
46
+
47
+ class BaseEvent(UniversalBaseModel):
48
+ id: UUID = Field(default_factory=uuid4)
49
+ timestamp: datetime = Field(default_factory=default_datetime_factory)
50
+ api_version: Literal["2024-10-25"] = "2024-10-25"
51
+ trace_id: UUID
52
+ span_id: UUID
@@ -0,0 +1,5 @@
1
+ from vellum.workflows.events.workflow import WorkflowEvent
2
+
3
+
4
+ def is_terminal_event(event: WorkflowEvent) -> bool:
5
+ return event.name in {"workflow.execution.fulfilled", "workflow.execution.rejected", "workflow.execution.paused"}
@@ -0,0 +1,139 @@
1
+ from typing import TYPE_CHECKING, Any, Dict, Generator, Generic, Iterable, Literal, Type, Union
2
+
3
+ from pydantic import field_serializer
4
+
5
+ from vellum.core.pydantic_utilities import UniversalBaseModel
6
+
7
+ from vellum.workflows.errors import VellumError
8
+ from vellum.workflows.outputs.base import BaseOutput
9
+ from vellum.workflows.references import ExternalInputReference
10
+ from vellum.workflows.types.generics import OutputsType, WorkflowInputsType
11
+
12
+ from .node import (
13
+ NodeExecutionFulfilledEvent,
14
+ NodeExecutionInitiatedEvent,
15
+ NodeExecutionPausedEvent,
16
+ NodeExecutionRejectedEvent,
17
+ NodeExecutionResumedEvent,
18
+ NodeExecutionStreamingEvent,
19
+ )
20
+ from .types import BaseEvent, default_serializer, serialize_type_encoder
21
+
22
+ if TYPE_CHECKING:
23
+ from vellum.workflows.workflows.base import BaseWorkflow
24
+
25
+
26
+ class _BaseWorkflowExecutionBody(UniversalBaseModel):
27
+ workflow_definition: Type["BaseWorkflow"]
28
+
29
+ @field_serializer("workflow_definition")
30
+ def serialize_workflow_definition(self, workflow_definition: Type, _info: Any) -> Dict[str, Any]:
31
+ return serialize_type_encoder(workflow_definition)
32
+
33
+
34
+ class WorkflowExecutionInitiatedBody(_BaseWorkflowExecutionBody, Generic[WorkflowInputsType]):
35
+ inputs: WorkflowInputsType
36
+
37
+ @field_serializer("inputs")
38
+ def serialize_inputs(self, inputs: WorkflowInputsType, _info: Any) -> Dict[str, Any]:
39
+ return default_serializer(inputs)
40
+
41
+
42
+ class WorkflowExecutionInitiatedEvent(BaseEvent, Generic[WorkflowInputsType]):
43
+ name: Literal["workflow.execution.initiated"] = "workflow.execution.initiated"
44
+ body: WorkflowExecutionInitiatedBody[WorkflowInputsType]
45
+
46
+ @property
47
+ def inputs(self) -> WorkflowInputsType:
48
+ return self.body.inputs
49
+
50
+
51
+ class WorkflowExecutionStreamingBody(_BaseWorkflowExecutionBody):
52
+ output: BaseOutput
53
+
54
+ @field_serializer("output")
55
+ def serialize_output(self, output: BaseOutput, _info: Any) -> Dict[str, Any]:
56
+ return default_serializer(output)
57
+
58
+
59
+ class WorkflowExecutionStreamingEvent(BaseEvent):
60
+ name: Literal["workflow.execution.streaming"] = "workflow.execution.streaming"
61
+ body: WorkflowExecutionStreamingBody
62
+
63
+ @property
64
+ def output(self) -> BaseOutput:
65
+ return self.body.output
66
+
67
+
68
+ class WorkflowExecutionFulfilledBody(_BaseWorkflowExecutionBody, Generic[OutputsType]):
69
+ outputs: OutputsType
70
+
71
+ @field_serializer("outputs")
72
+ def serialize_outputs(self, outputs: OutputsType, _info: Any) -> Dict[str, Any]:
73
+ return default_serializer(outputs)
74
+
75
+
76
+ class WorkflowExecutionFulfilledEvent(BaseEvent, Generic[OutputsType]):
77
+ name: Literal["workflow.execution.fulfilled"] = "workflow.execution.fulfilled"
78
+ body: WorkflowExecutionFulfilledBody[OutputsType]
79
+
80
+ @property
81
+ def outputs(self) -> OutputsType:
82
+ return self.body.outputs
83
+
84
+
85
+ class WorkflowExecutionRejectedBody(_BaseWorkflowExecutionBody):
86
+ error: VellumError
87
+
88
+
89
+ class WorkflowExecutionRejectedEvent(BaseEvent):
90
+ name: Literal["workflow.execution.rejected"] = "workflow.execution.rejected"
91
+ body: WorkflowExecutionRejectedBody
92
+
93
+ @property
94
+ def error(self) -> VellumError:
95
+ return self.body.error
96
+
97
+
98
+ class WorkflowExecutionPausedBody(_BaseWorkflowExecutionBody):
99
+ external_inputs: Iterable[ExternalInputReference]
100
+
101
+
102
+ class WorkflowExecutionPausedEvent(BaseEvent):
103
+ name: Literal["workflow.execution.paused"] = "workflow.execution.paused"
104
+ body: WorkflowExecutionPausedBody
105
+
106
+ @property
107
+ def external_inputs(self) -> Iterable[ExternalInputReference]:
108
+ return self.body.external_inputs
109
+
110
+
111
+ class WorkflowExecutionResumedBody(_BaseWorkflowExecutionBody):
112
+ pass
113
+
114
+
115
+ class WorkflowExecutionResumedEvent(BaseEvent):
116
+ name: Literal["workflow.execution.resumed"] = "workflow.execution.resumed"
117
+ body: WorkflowExecutionResumedBody
118
+
119
+
120
+ GenericWorkflowEvent = Union[
121
+ WorkflowExecutionStreamingEvent,
122
+ WorkflowExecutionRejectedEvent,
123
+ WorkflowExecutionPausedEvent,
124
+ WorkflowExecutionResumedEvent,
125
+ NodeExecutionInitiatedEvent,
126
+ NodeExecutionStreamingEvent,
127
+ NodeExecutionFulfilledEvent,
128
+ NodeExecutionRejectedEvent,
129
+ NodeExecutionPausedEvent,
130
+ NodeExecutionResumedEvent,
131
+ ]
132
+
133
+ WorkflowEvent = Union[
134
+ GenericWorkflowEvent,
135
+ WorkflowExecutionInitiatedEvent,
136
+ WorkflowExecutionFulfilledEvent,
137
+ ]
138
+
139
+ WorkflowEventStream = Generator[WorkflowEvent, None, None]
@@ -0,0 +1,15 @@
1
+ from vellum.workflows.errors import VellumError, VellumErrorCode
2
+
3
+
4
+ class NodeException(Exception):
5
+ def __init__(self, message: str, code: VellumErrorCode):
6
+ self.message = message
7
+ self.code = code
8
+ super().__init__(message)
9
+
10
+ @property
11
+ def error(self) -> VellumError:
12
+ return VellumError(
13
+ message=self.message,
14
+ code=self.code,
15
+ )
File without changes