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,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 LessThanExpression(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 LessThanOrEqualToExpression(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,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 NotBetweenExpression(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 not 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 value < start or value > end
@@ -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 NotInExpression(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 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 not 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 contains, got: {rhs.__class__.__name__}")
30
+
31
+ return lhs not in rhs
@@ -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 OrExpression(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} or {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 lhs
31
+
32
+ return resolve_value(self._rhs, state)
@@ -0,0 +1,3 @@
1
+ from .graph import Graph, GraphTarget
2
+
3
+ __all__ = ["Graph", "GraphTarget"]
@@ -0,0 +1,131 @@
1
+ from typing import TYPE_CHECKING, Iterator, List, Set, Type, Union
2
+
3
+ from orderly_set import OrderedSet
4
+
5
+ from vellum.workflows.edges.edge import Edge
6
+ from vellum.workflows.types.generics import NodeType
7
+
8
+ if TYPE_CHECKING:
9
+ from vellum.workflows.nodes.bases.base import BaseNode
10
+ from vellum.workflows.ports.port import Port
11
+
12
+ GraphTargetOfSets = Union[
13
+ Set[NodeType],
14
+ Set["Graph"],
15
+ Set[Union[Type["BaseNode"], "Graph"]],
16
+ ]
17
+
18
+ GraphTarget = Union[
19
+ Type["BaseNode"],
20
+ "Graph",
21
+ GraphTargetOfSets,
22
+ ]
23
+
24
+
25
+ class Graph:
26
+ _entrypoints: Set["Port"]
27
+ _edges: List[Edge]
28
+ _terminals: Set["Port"]
29
+
30
+ def __init__(self, entrypoints: Set["Port"], edges: List[Edge], terminals: Set["Port"]):
31
+ self._edges = edges
32
+ self._entrypoints = entrypoints
33
+ self._terminals = terminals
34
+
35
+ @staticmethod
36
+ def from_port(port: "Port") -> "Graph":
37
+ ports = {port}
38
+ return Graph(entrypoints=ports, edges=[], terminals=ports)
39
+
40
+ @staticmethod
41
+ def from_node(node: Type["BaseNode"]) -> "Graph":
42
+ ports = {port for port in node.Ports}
43
+ return Graph(entrypoints=ports, edges=[], terminals=ports)
44
+
45
+ @staticmethod
46
+ def from_set(targets: GraphTargetOfSets) -> "Graph":
47
+ entrypoints = set()
48
+ edges = OrderedSet[Edge]()
49
+ terminals = set()
50
+
51
+ for target in targets:
52
+ if isinstance(target, Graph):
53
+ entrypoints.update(target._entrypoints)
54
+ edges.update(target._edges)
55
+ terminals.update(target._terminals)
56
+ else:
57
+ entrypoints.update({port for port in target.Ports})
58
+ terminals.update({port for port in target.Ports})
59
+
60
+ return Graph(entrypoints=entrypoints, edges=list(edges), terminals=terminals)
61
+
62
+ @staticmethod
63
+ def from_edge(edge: Edge) -> "Graph":
64
+ return Graph(entrypoints={edge.from_port}, edges=[edge], terminals={port for port in edge.to_node.Ports})
65
+
66
+ def __rshift__(self, other: GraphTarget) -> "Graph":
67
+ if not self._edges and not self._entrypoints:
68
+ raise ValueError("Graph instance can only create new edges from nodes within existing edges")
69
+
70
+ if isinstance(other, set):
71
+ new_terminals = set()
72
+ for elem in other:
73
+ for final_output_node in self._terminals:
74
+ if isinstance(elem, Graph):
75
+ midgraph = final_output_node >> set(elem.entrypoints)
76
+ self._extend_edges(midgraph.edges)
77
+ self._extend_edges(elem.edges)
78
+ for other_terminal in elem._terminals:
79
+ new_terminals.add(other_terminal)
80
+ else:
81
+ midgraph = final_output_node >> elem
82
+ self._extend_edges(midgraph.edges)
83
+ for other_terminal in elem.Ports:
84
+ new_terminals.add(other_terminal)
85
+ self._terminals = new_terminals
86
+ return self
87
+
88
+ if isinstance(other, Graph):
89
+ for final_output_node in self._terminals:
90
+ midgraph = final_output_node >> set(other.entrypoints)
91
+ self._extend_edges(midgraph.edges)
92
+ self._extend_edges(other.edges)
93
+ self._terminals = other._terminals
94
+ return self
95
+
96
+ for final_output_node in self._terminals:
97
+ subgraph = final_output_node >> other
98
+ self._extend_edges(subgraph.edges)
99
+ self._terminals = {port for port in other.Ports}
100
+ return self
101
+
102
+ @property
103
+ def entrypoints(self) -> Iterator[Type["BaseNode"]]:
104
+ return iter(e.node_class for e in self._entrypoints)
105
+
106
+ @property
107
+ def edges(self) -> Iterator[Edge]:
108
+ return iter(self._edges)
109
+
110
+ @property
111
+ def nodes(self) -> Iterator[Type["BaseNode"]]:
112
+ nodes = set()
113
+ if not self._edges:
114
+ for node in self.entrypoints:
115
+ if node not in nodes:
116
+ nodes.add(node)
117
+ yield node
118
+ return
119
+
120
+ for edge in self._edges:
121
+ if edge.from_port.node_class not in nodes:
122
+ nodes.add(edge.from_port.node_class)
123
+ yield edge.from_port.node_class
124
+ if edge.to_node not in nodes:
125
+ nodes.add(edge.to_node)
126
+ yield edge.to_node
127
+
128
+ def _extend_edges(self, edges: Iterator[Edge]) -> None:
129
+ for edge in edges:
130
+ if edge not in self._edges:
131
+ self._edges.append(edge)
File without changes