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,52 @@
1
+ from collections.abc import Mapping
2
+ import dataclasses
3
+ from typing import Any, Sequence, Type, TypeVar
4
+
5
+ from pydantic import BaseModel, GetCoreSchemaHandler
6
+ from pydantic_core import core_schema
7
+
8
+ from vellum.workflows.descriptors.base import BaseDescriptor
9
+ from vellum.workflows.descriptors.utils import resolve_value
10
+ from vellum.workflows.state.base import BaseState
11
+
12
+ LHS = TypeVar("LHS")
13
+
14
+
15
+ class AccessorExpression(BaseDescriptor[Any]):
16
+ def __init__(
17
+ self,
18
+ *,
19
+ base: BaseDescriptor[LHS],
20
+ field: str,
21
+ ) -> None:
22
+ super().__init__(
23
+ name=f"{base.name}.{field}",
24
+ types=(),
25
+ instance=None,
26
+ )
27
+ self._base = base
28
+ self._field = field
29
+
30
+ def resolve(self, state: "BaseState") -> Any:
31
+ base = resolve_value(self._base, state)
32
+
33
+ if dataclasses.is_dataclass(base):
34
+ return getattr(base, self._field)
35
+
36
+ if isinstance(base, BaseModel):
37
+ return getattr(base, self._field)
38
+
39
+ if isinstance(base, Mapping):
40
+ return base[self._field]
41
+
42
+ if isinstance(base, Sequence):
43
+ index = int(self._field)
44
+ return base[index]
45
+
46
+ raise ValueError(f"Cannot get field {self._field} from {base}")
47
+
48
+ @classmethod
49
+ def __get_pydantic_core_schema__(
50
+ cls, source_type: Type[Any], handler: GetCoreSchemaHandler
51
+ ) -> core_schema.CoreSchema:
52
+ return core_schema.is_instance_schema(cls)
@@ -0,0 +1,32 @@
1
+ from typing import TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+ from vellum.workflows.types.utils import resolve_combined_types
7
+
8
+ LHS = TypeVar("LHS")
9
+ RHS = TypeVar("RHS")
10
+
11
+
12
+ class AndExpression(BaseDescriptor[Union[LHS, RHS]]):
13
+ def __init__(
14
+ self,
15
+ *,
16
+ lhs: Union[BaseDescriptor[LHS], LHS],
17
+ rhs: Union[BaseDescriptor[RHS], RHS],
18
+ ) -> None:
19
+ super().__init__(
20
+ name=f"{lhs} and {rhs}",
21
+ types=resolve_combined_types(lhs, rhs),
22
+ instance=None,
23
+ )
24
+ self._lhs = lhs
25
+ self._rhs = rhs
26
+
27
+ def resolve(self, state: "BaseState") -> Union[LHS, RHS]:
28
+ lhs = resolve_value(self._lhs, state)
29
+ if lhs:
30
+ return resolve_value(self._rhs, state)
31
+
32
+ return lhs
@@ -0,0 +1,31 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ LHS = TypeVar("LHS")
8
+ RHS = TypeVar("RHS")
9
+
10
+
11
+ class BeginsWithExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ lhs: Union[BaseDescriptor[LHS], LHS],
16
+ rhs: Union[BaseDescriptor[RHS], RHS],
17
+ ) -> None:
18
+ super().__init__(name=f"{lhs} begins with {rhs}", types=(bool,))
19
+ self._lhs = lhs
20
+ self._rhs = rhs
21
+
22
+ def resolve(self, state: "BaseState") -> bool:
23
+ lhs = resolve_value(self._lhs, state)
24
+ rhs = resolve_value(self._rhs, state)
25
+ if not isinstance(lhs, str):
26
+ raise ValueError(f"Expected LHS to be a string, got {type(lhs)}")
27
+
28
+ if not isinstance(rhs, str):
29
+ raise ValueError(f"Expected RHS to be a string, got {type(rhs)}")
30
+
31
+ return lhs.startswith(rhs)
@@ -0,0 +1,38 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ _V = TypeVar("_V")
8
+ _S = TypeVar("_S")
9
+ _E = TypeVar("_E")
10
+
11
+
12
+ class BetweenExpression(BaseDescriptor[bool], Generic[_V, _S, _E]):
13
+ def __init__(
14
+ self,
15
+ *,
16
+ value: Union[BaseDescriptor[_V], _V],
17
+ start: Union[BaseDescriptor[_S], _S],
18
+ end: Union[BaseDescriptor[_E], _E],
19
+ ) -> None:
20
+ super().__init__(name=f"{value} is between {start} and {end}", types=(bool,))
21
+ self._value = value
22
+ self._start = start
23
+ self._end = end
24
+
25
+ def resolve(self, state: "BaseState") -> bool:
26
+ value = resolve_value(self._value, state)
27
+ if not isinstance(value, (int, float)):
28
+ raise ValueError(f"Expected a numeric value, got: {value.__class__.__name__}")
29
+
30
+ start = resolve_value(self._start, state)
31
+ if not isinstance(start, (int, float)):
32
+ raise ValueError(f"Expected a numeric start value, got: {start.__class__.__name__}")
33
+
34
+ end = resolve_value(self._end, state)
35
+ if not isinstance(end, (int, float)):
36
+ raise ValueError(f"Expected a numeric end value, got: {end.__class__.__name__}")
37
+
38
+ return start <= value <= end
@@ -0,0 +1,41 @@
1
+ from typing import TypeVar, Union
2
+
3
+ from vellum.workflows.constants import UNDEF
4
+ from vellum.workflows.descriptors.base import BaseDescriptor
5
+ from vellum.workflows.descriptors.utils import resolve_value
6
+ from vellum.workflows.state.base import BaseState
7
+ from vellum.workflows.types.utils import resolve_combined_types
8
+
9
+ LHS = TypeVar("LHS")
10
+ RHS = TypeVar("RHS")
11
+
12
+
13
+ class CoalesceExpression(BaseDescriptor[Union[LHS, RHS]]):
14
+ def __init__(
15
+ self,
16
+ *,
17
+ lhs: Union[BaseDescriptor[LHS], LHS],
18
+ rhs: Union[BaseDescriptor[RHS], RHS],
19
+ ) -> None:
20
+ super().__init__(
21
+ name=f"{lhs} ?? {rhs}",
22
+ types=resolve_combined_types(lhs, rhs),
23
+ instance=None,
24
+ )
25
+ self._lhs = lhs
26
+ self._rhs = rhs
27
+
28
+ def resolve(self, state: "BaseState") -> Union[LHS, RHS]:
29
+ lhs = resolve_value(self._lhs, state)
30
+ if lhs is not UNDEF and lhs is not None:
31
+ return lhs
32
+
33
+ return resolve_value(self._rhs, state)
34
+
35
+ @property
36
+ def lhs(self) -> Union[BaseDescriptor[LHS], LHS]:
37
+ return self._lhs
38
+
39
+ @property
40
+ def rhs(self) -> Union[BaseDescriptor[RHS], RHS]:
41
+ return self._rhs
@@ -0,0 +1,30 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ LHS = TypeVar("LHS")
8
+ RHS = TypeVar("RHS")
9
+
10
+
11
+ class ContainsExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ lhs: Union[BaseDescriptor[LHS], LHS],
16
+ rhs: Union[BaseDescriptor[RHS], RHS],
17
+ ) -> None:
18
+ super().__init__(name=f"{lhs} contains {rhs}", types=(bool,))
19
+ self._lhs = lhs
20
+ self._rhs = rhs
21
+
22
+ def resolve(self, state: "BaseState") -> bool:
23
+ # Support any type that implements the in operator
24
+ # https://app.shortcut.com/vellum/story/4658
25
+ lhs = resolve_value(self._lhs, state)
26
+ if not isinstance(lhs, (list, tuple, set, dict, str)):
27
+ raise ValueError(f"Expected a LHS that supported contains, got: {lhs.__class__.__name__}")
28
+
29
+ rhs = resolve_value(self._rhs, state)
30
+ return rhs in lhs
@@ -0,0 +1,31 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ LHS = TypeVar("LHS")
8
+ RHS = TypeVar("RHS")
9
+
10
+
11
+ class DoesNotBeginWithExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ lhs: Union[BaseDescriptor[LHS], LHS],
16
+ rhs: Union[BaseDescriptor[RHS], RHS],
17
+ ) -> None:
18
+ super().__init__(name=f"{lhs} not begins with {rhs}", types=(bool,))
19
+ self._lhs = lhs
20
+ self._rhs = rhs
21
+
22
+ def resolve(self, state: "BaseState") -> bool:
23
+ lhs = resolve_value(self._lhs, state)
24
+ rhs = resolve_value(self._rhs, state)
25
+ if not isinstance(lhs, str):
26
+ raise ValueError(f"Expected LHS to be a string, got {type(lhs)}")
27
+
28
+ if not isinstance(rhs, str):
29
+ raise ValueError(f"Expected RHS to be a string, got {type(rhs)}")
30
+
31
+ return not lhs.startswith(rhs)
@@ -0,0 +1,30 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ LHS = TypeVar("LHS")
8
+ RHS = TypeVar("RHS")
9
+
10
+
11
+ class DoesNotContainExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ lhs: Union[BaseDescriptor[LHS], LHS],
16
+ rhs: Union[BaseDescriptor[RHS], RHS],
17
+ ) -> None:
18
+ super().__init__(name=f"{lhs} does not contain {rhs}", types=(bool,))
19
+ self._lhs = lhs
20
+ self._rhs = rhs
21
+
22
+ def resolve(self, state: "BaseState") -> bool:
23
+ # Support any type that implements the not in operator
24
+ # https://app.shortcut.com/vellum/story/4658
25
+ lhs = resolve_value(self._lhs, state)
26
+ if not isinstance(lhs, (list, tuple, set, dict, str)):
27
+ raise ValueError(f"Expected a LHS that supported contains, got: {lhs.__class__.__name__}")
28
+
29
+ rhs = resolve_value(self._rhs, state)
30
+ return rhs not in lhs
@@ -0,0 +1,31 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ LHS = TypeVar("LHS")
8
+ RHS = TypeVar("RHS")
9
+
10
+
11
+ class DoesNotEndWithExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ lhs: Union[BaseDescriptor[LHS], LHS],
16
+ rhs: Union[BaseDescriptor[RHS], RHS],
17
+ ) -> None:
18
+ super().__init__(name=f"{lhs} not ends with {rhs}", types=(bool,))
19
+ self._lhs = lhs
20
+ self._rhs = rhs
21
+
22
+ def resolve(self, state: "BaseState") -> bool:
23
+ lhs = resolve_value(self._lhs, state)
24
+ rhs = resolve_value(self._rhs, state)
25
+ if not isinstance(lhs, str):
26
+ raise ValueError(f"Expected LHS to be a string, got {type(lhs)}")
27
+
28
+ if not isinstance(rhs, str):
29
+ raise ValueError(f"Expected RHS to be a string, got {type(rhs)}")
30
+
31
+ return not lhs.endswith(rhs)
@@ -0,0 +1,25 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ LHS = TypeVar("LHS")
8
+ RHS = TypeVar("RHS")
9
+
10
+
11
+ class DoesNotEqualExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ lhs: Union[BaseDescriptor[LHS], LHS],
16
+ rhs: Union[BaseDescriptor[RHS], RHS],
17
+ ) -> None:
18
+ super().__init__(name=f"{lhs} != {rhs}", types=(bool,))
19
+ self._lhs = lhs
20
+ self._rhs = rhs
21
+
22
+ def resolve(self, state: "BaseState") -> bool:
23
+ lhs = resolve_value(self._lhs, state)
24
+ rhs = resolve_value(self._rhs, state)
25
+ return lhs != rhs
@@ -0,0 +1,31 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ LHS = TypeVar("LHS")
8
+ RHS = TypeVar("RHS")
9
+
10
+
11
+ class EndsWithExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ lhs: Union[BaseDescriptor[LHS], LHS],
16
+ rhs: Union[BaseDescriptor[RHS], RHS],
17
+ ) -> None:
18
+ super().__init__(name=f"{lhs} ends with {rhs}", types=(bool,))
19
+ self._lhs = lhs
20
+ self._rhs = rhs
21
+
22
+ def resolve(self, state: "BaseState") -> bool:
23
+ lhs = resolve_value(self._lhs, state)
24
+ rhs = resolve_value(self._rhs, state)
25
+ if not isinstance(lhs, str):
26
+ raise ValueError(f"Expected LHS to be a string, got {type(lhs)}")
27
+
28
+ if not isinstance(rhs, str):
29
+ raise ValueError(f"Expected RHS to be a string, got {type(rhs)}")
30
+
31
+ return lhs.endswith(rhs)
@@ -0,0 +1,25 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ LHS = TypeVar("LHS")
8
+ RHS = TypeVar("RHS")
9
+
10
+
11
+ class EqualsExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ lhs: Union[BaseDescriptor[LHS], LHS],
16
+ rhs: Union[BaseDescriptor[RHS], RHS],
17
+ ) -> None:
18
+ super().__init__(name=f"{lhs} == {rhs}", types=(bool,))
19
+ self._lhs = lhs
20
+ self._rhs = rhs
21
+
22
+ def resolve(self, state: "BaseState") -> bool:
23
+ lhs = resolve_value(self._lhs, state)
24
+ rhs = resolve_value(self._rhs, state)
25
+ return lhs == rhs
@@ -0,0 +1,33 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ LHS = TypeVar("LHS")
8
+ RHS = TypeVar("RHS")
9
+
10
+
11
+ class GreaterThanExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ lhs: Union[BaseDescriptor[LHS], LHS],
16
+ rhs: Union[BaseDescriptor[RHS], RHS],
17
+ ) -> None:
18
+ super().__init__(name=f"{lhs} > {rhs}", types=(bool,))
19
+ self._lhs = lhs
20
+ self._rhs = rhs
21
+
22
+ def resolve(self, state: "BaseState") -> bool:
23
+ # Support any type that implements the > operator
24
+ # https://app.shortcut.com/vellum/story/4658
25
+ lhs = resolve_value(self._lhs, state)
26
+ if not isinstance(lhs, (int, float)):
27
+ raise ValueError(f"Expected a numeric lhs value, got: {lhs.__class__.__name__}")
28
+
29
+ rhs = resolve_value(self._rhs, state)
30
+ if not isinstance(rhs, (int, float)):
31
+ raise ValueError(f"Expected a numeric rhs value, got: {rhs.__class__.__name__}")
32
+
33
+ return lhs > rhs
@@ -0,0 +1,33 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ LHS = TypeVar("LHS")
8
+ RHS = TypeVar("RHS")
9
+
10
+
11
+ class GreaterThanOrEqualToExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ lhs: Union[BaseDescriptor[LHS], LHS],
16
+ rhs: Union[BaseDescriptor[RHS], RHS],
17
+ ) -> None:
18
+ super().__init__(name=f"{lhs} >= {rhs}", types=(bool,))
19
+ self._lhs = lhs
20
+ self._rhs = rhs
21
+
22
+ def resolve(self, state: "BaseState") -> bool:
23
+ # Support any type that implements the >= operator
24
+ # https://app.shortcut.com/vellum/story/4658
25
+ lhs = resolve_value(self._lhs, state)
26
+ if not isinstance(lhs, (int, float)):
27
+ raise ValueError(f"Expected a numeric lhs value, got: {lhs.__class__.__name__}")
28
+
29
+ rhs = resolve_value(self._rhs, state)
30
+ if not isinstance(rhs, (int, float)):
31
+ raise ValueError(f"Expected a numeric rhs value, got: {rhs.__class__.__name__}")
32
+
33
+ return lhs >= rhs
@@ -0,0 +1,31 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ LHS = TypeVar("LHS")
8
+ RHS = TypeVar("RHS")
9
+
10
+
11
+ class InExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ lhs: Union[BaseDescriptor[LHS], LHS],
16
+ rhs: Union[BaseDescriptor[RHS], RHS],
17
+ ) -> None:
18
+ super().__init__(name=f"{lhs} in {rhs}", types=(bool,))
19
+ self._lhs = lhs
20
+ self._rhs = rhs
21
+
22
+ def resolve(self, state: "BaseState") -> bool:
23
+ # Support any type that implements the in operator
24
+ # https://app.shortcut.com/vellum/story/4658
25
+ lhs = resolve_value(self._lhs, state)
26
+
27
+ rhs = resolve_value(self._rhs, state)
28
+ if not isinstance(rhs, (list, tuple, set, dict, str)):
29
+ raise ValueError(f"Expected a RHS that supported in, got: {rhs.__class__.__name__}")
30
+
31
+ return lhs in rhs
@@ -0,0 +1,24 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ _T = TypeVar("_T")
8
+
9
+
10
+ class IsBlankExpression(BaseDescriptor[bool], Generic[_T]):
11
+ def __init__(
12
+ self,
13
+ *,
14
+ expression: Union[BaseDescriptor[_T], _T],
15
+ ) -> None:
16
+ super().__init__(name=f"{expression} is blank", types=(bool,))
17
+ self._expression = expression
18
+
19
+ def resolve(self, state: "BaseState") -> bool:
20
+ expression = resolve_value(self._expression, state)
21
+ if not isinstance(expression, str):
22
+ raise ValueError(f"Expected a string expression, got: {expression.__class__.__name__}")
23
+
24
+ return len(expression) == 0
@@ -0,0 +1,24 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ _T = TypeVar("_T")
8
+
9
+
10
+ class IsNotBlankExpression(BaseDescriptor[bool], Generic[_T]):
11
+ def __init__(
12
+ self,
13
+ *,
14
+ expression: Union[BaseDescriptor[_T], _T],
15
+ ) -> None:
16
+ super().__init__(name=f"{expression} is not blank", types=(bool,))
17
+ self._expression = expression
18
+
19
+ def resolve(self, state: "BaseState") -> bool:
20
+ expression = resolve_value(self._expression, state)
21
+ if not isinstance(expression, str):
22
+ raise ValueError(f"Expected a string expression, got: {expression.__class__.__name__}")
23
+
24
+ return len(expression) != 0
@@ -0,0 +1,21 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ _T = TypeVar("_T")
8
+
9
+
10
+ class IsNotNullExpression(BaseDescriptor[bool], Generic[_T]):
11
+ def __init__(
12
+ self,
13
+ *,
14
+ expression: Union[BaseDescriptor[_T], _T],
15
+ ) -> None:
16
+ super().__init__(name=f"{expression} is not None", types=(bool,))
17
+ self._expression = expression
18
+
19
+ def resolve(self, state: "BaseState") -> bool:
20
+ expression = resolve_value(self._expression, state)
21
+ return expression is not None
@@ -0,0 +1,22 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.constants import UNDEF
4
+ from vellum.workflows.descriptors.base import BaseDescriptor
5
+ from vellum.workflows.descriptors.utils import resolve_value
6
+ from vellum.workflows.state.base import BaseState
7
+
8
+ _T = TypeVar("_T")
9
+
10
+
11
+ class IsNotUndefinedExpression(BaseDescriptor[bool], Generic[_T]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ expression: Union[BaseDescriptor[_T], _T],
16
+ ) -> None:
17
+ super().__init__(name=f"{expression} is not undefined", types=(bool,))
18
+ self._expression = expression
19
+
20
+ def resolve(self, state: "BaseState") -> bool:
21
+ expression = resolve_value(self._expression, state)
22
+ return expression is not UNDEF
@@ -0,0 +1,21 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.descriptors.base import BaseDescriptor
4
+ from vellum.workflows.descriptors.utils import resolve_value
5
+ from vellum.workflows.state.base import BaseState
6
+
7
+ _T = TypeVar("_T")
8
+
9
+
10
+ class IsNullExpression(BaseDescriptor[bool], Generic[_T]):
11
+ def __init__(
12
+ self,
13
+ *,
14
+ expression: Union[BaseDescriptor[_T], _T],
15
+ ) -> None:
16
+ super().__init__(name=f"{expression} is None", types=(bool,))
17
+ self._expression = expression
18
+
19
+ def resolve(self, state: "BaseState") -> bool:
20
+ expression = resolve_value(self._expression, state)
21
+ return expression is None
@@ -0,0 +1,22 @@
1
+ from typing import Generic, TypeVar, Union
2
+
3
+ from vellum.workflows.constants import UNDEF
4
+ from vellum.workflows.descriptors.base import BaseDescriptor
5
+ from vellum.workflows.descriptors.utils import resolve_value
6
+ from vellum.workflows.state.base import BaseState
7
+
8
+ _T = TypeVar("_T")
9
+
10
+
11
+ class IsUndefinedExpression(BaseDescriptor[bool], Generic[_T]):
12
+ def __init__(
13
+ self,
14
+ *,
15
+ expression: Union[BaseDescriptor[_T], _T],
16
+ ) -> None:
17
+ super().__init__(name=f"{expression} is undefined", types=(bool,))
18
+ self._expression = expression
19
+
20
+ def resolve(self, state: "BaseState") -> bool:
21
+ expression = resolve_value(self._expression, state)
22
+ return expression is UNDEF