vellum-ai 0.9.16rc2__py3-none-any.whl → 0.9.16rc4__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 (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