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,205 @@
1
+ from uuid import UUID
2
+ from typing import Any, ClassVar, Dict, Generic, Optional, TypeVar, cast
3
+
4
+ from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
5
+ from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
6
+ from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
7
+ from vellum_ee.workflows.display.types import WorkflowDisplayContext
8
+ from vellum.workflows.nodes.displayable import APINode
9
+ from vellum.workflows.references.output import OutputReference
10
+ from vellum.workflows.types.core import JsonArray, JsonObject
11
+
12
+ _APINodeType = TypeVar("_APINodeType", bound=APINode)
13
+
14
+
15
+ class BaseAPINodeDisplay(BaseNodeVellumDisplay[_APINodeType], Generic[_APINodeType]):
16
+ url_input_id: ClassVar[Optional[UUID]] = None
17
+ method_input_id: ClassVar[Optional[UUID]] = None
18
+ body_input_id: ClassVar[Optional[UUID]] = None
19
+
20
+ authorization_type_input_id: ClassVar[Optional[UUID]] = None
21
+ bearer_token_value_input_id: ClassVar[Optional[UUID]] = None
22
+ api_key_header_key_input_id: ClassVar[Optional[UUID]] = None
23
+ api_key_header_value_input_id: ClassVar[Optional[UUID]] = None
24
+
25
+ text_output_id: ClassVar[Optional[UUID]] = None
26
+ json_output_id: ClassVar[Optional[UUID]] = None
27
+ status_code_output_id: ClassVar[Optional[UUID]] = None
28
+
29
+ # A mapping between node input keys and their ids for inputs representing additional header keys
30
+ additional_header_key_input_ids: ClassVar[Optional[Dict[str, UUID]]] = None
31
+
32
+ # A mapping between node input keys and their ids for inputs representing additional header values
33
+ additional_header_value_input_ids: ClassVar[Optional[Dict[str, UUID]]] = None
34
+
35
+ def serialize(
36
+ self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **kwargs: Any
37
+ ) -> JsonObject:
38
+ node = self._node
39
+ node_id = self.node_id
40
+
41
+ node_url = raise_if_descriptor(node.url)
42
+ url_node_input = create_node_input(
43
+ node_id=node_id,
44
+ input_name="url",
45
+ value=node_url,
46
+ display_context=display_context,
47
+ input_id=self.url_input_id,
48
+ )
49
+
50
+ node_method = raise_if_descriptor(node.method)
51
+ method_node_input = create_node_input(
52
+ node_id=node_id,
53
+ input_name="method",
54
+ value=node_method,
55
+ display_context=display_context,
56
+ input_id=self.method_input_id,
57
+ )
58
+
59
+ node_data = raise_if_descriptor(node.data)
60
+ node_json = raise_if_descriptor(node.json)
61
+ body_node_input = create_node_input(
62
+ node_id=node_id,
63
+ input_name="body",
64
+ value=node_data if node_data else node_json,
65
+ display_context=display_context,
66
+ input_id=self.body_input_id,
67
+ )
68
+
69
+ headers = raise_if_descriptor(node.headers)
70
+ api_key_header_key = raise_if_descriptor(node.api_key_header_key)
71
+ authorization_type = raise_if_descriptor(node.authorization_type)
72
+ bearer_token_value = raise_if_descriptor(node.bearer_token_value)
73
+
74
+ authorization_type_node_input = (
75
+ create_node_input(
76
+ node_id=node_id,
77
+ input_name="authorization_type",
78
+ value=authorization_type,
79
+ display_context=display_context,
80
+ input_id=self.authorization_type_input_id,
81
+ )
82
+ if authorization_type
83
+ else None
84
+ )
85
+ bearer_token_value_node_input = (
86
+ create_node_input(
87
+ node_id=node_id,
88
+ input_name="bearer_token_value",
89
+ value=bearer_token_value,
90
+ display_context=display_context,
91
+ input_id=self.bearer_token_value_input_id,
92
+ )
93
+ if bearer_token_value
94
+ else None
95
+ )
96
+ api_key_header_key_node_input = (
97
+ create_node_input(
98
+ node_id=node_id,
99
+ input_name="api_key_header_key",
100
+ value=api_key_header_key,
101
+ display_context=display_context,
102
+ input_id=self.api_key_header_key_input_id,
103
+ )
104
+ if api_key_header_key
105
+ else None
106
+ )
107
+ api_key_header_value_node_input = (
108
+ create_node_input(
109
+ node_id=node_id,
110
+ input_name="api_key_header_value",
111
+ value=node.api_key_header_value,
112
+ display_context=display_context,
113
+ input_id=self.api_key_header_value_input_id,
114
+ )
115
+ if headers and api_key_header_key
116
+ else None
117
+ )
118
+
119
+ # TODO: Add stable IDs for additional headers
120
+ # https://app.shortcut.com/vellum/story/5083
121
+ additional_headers: JsonArray = (
122
+ [
123
+ {
124
+ "header_key_input_id": create_node_input(
125
+ node_id=node_id,
126
+ input_name=f"additional_header_key_{key}",
127
+ value=key,
128
+ display_context=display_context,
129
+ input_id=(
130
+ self.additional_header_key_input_ids.get(key)
131
+ if self.additional_header_key_input_ids
132
+ else None
133
+ ),
134
+ ).id,
135
+ "header_value_input_id": create_node_input(
136
+ node_id=node_id,
137
+ input_name=f"additional_header_value_{key}",
138
+ value=value,
139
+ display_context=display_context,
140
+ input_id=(
141
+ self.additional_header_value_input_ids.get(key)
142
+ if self.additional_header_value_input_ids
143
+ else None
144
+ ),
145
+ ).id,
146
+ }
147
+ for key, value in headers.items()
148
+ if key not in {api_key_header_key, "Authorization"}
149
+ ]
150
+ if headers
151
+ else []
152
+ )
153
+
154
+ inputs = [
155
+ input
156
+ for input in [
157
+ url_node_input,
158
+ method_node_input,
159
+ body_node_input,
160
+ authorization_type_node_input,
161
+ bearer_token_value_node_input,
162
+ api_key_header_key_node_input,
163
+ api_key_header_value_node_input,
164
+ ]
165
+ if input is not None
166
+ ]
167
+
168
+ _, text_output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.text)]
169
+ _, json_output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.json)]
170
+ _, status_code_output_display = display_context.node_output_displays[
171
+ cast(OutputReference, node.Outputs.status_code)
172
+ ]
173
+
174
+ return {
175
+ "id": str(node_id),
176
+ "type": "API",
177
+ "inputs": [input.dict() for input in inputs],
178
+ "data": {
179
+ "label": self.label,
180
+ "error_output_id": str(error_output_id) if error_output_id else None,
181
+ "source_handle_id": str(self.get_source_handle_id(display_context.port_displays)),
182
+ "target_handle_id": str(self.get_target_handle_id()),
183
+ "url_input_id": url_node_input.id,
184
+ "method_input_id": method_node_input.id,
185
+ "body_input_id": body_node_input.id,
186
+ "authorization_type_input_id": (
187
+ authorization_type_node_input.id if authorization_type_node_input else None
188
+ ),
189
+ "bearer_token_value_input_id": (
190
+ bearer_token_value_node_input.id if bearer_token_value_node_input else None
191
+ ),
192
+ "api_key_header_key_input_id": (
193
+ api_key_header_key_node_input.id if api_key_header_key_node_input else None
194
+ ),
195
+ "api_key_header_value_input_id": (
196
+ api_key_header_value_node_input.id if api_key_header_value_node_input else None
197
+ ),
198
+ "additional_headers": additional_headers,
199
+ "text_output_id": str(text_output_display.id),
200
+ "json_output_id": str(json_output_display.id),
201
+ "status_code_output_id": str(status_code_output_display.id),
202
+ },
203
+ "display_data": self.get_display_data().dict(),
204
+ "definition": self.get_definition().dict(),
205
+ }
@@ -0,0 +1,71 @@
1
+ from uuid import UUID
2
+ from typing import ClassVar, Generic, Optional, TypeVar
3
+
4
+ from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
5
+ from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
6
+ from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
7
+ from vellum_ee.workflows.display.types import WorkflowDisplayContext
8
+ from vellum.workflows.nodes.displayable.code_execution_node import CodeExecutionNode
9
+ from vellum.workflows.nodes.displayable.code_execution_node.utils import read_file_from_path
10
+ from vellum.workflows.types.core import JsonObject
11
+ from vellum.workflows.utils.vellum_variables import primitive_type_to_vellum_variable_type
12
+
13
+ _CodeExecutionNodeType = TypeVar("_CodeExecutionNodeType", bound=CodeExecutionNode)
14
+
15
+
16
+ class BaseCodeExecutionNodeDisplay(BaseNodeVellumDisplay[_CodeExecutionNodeType], Generic[_CodeExecutionNodeType]):
17
+ code_input_id: ClassVar[Optional[UUID]] = None
18
+ runtime_input_id: ClassVar[Optional[UUID]] = None
19
+
20
+ output_id: ClassVar[Optional[UUID]] = None
21
+ log_output_id: ClassVar[Optional[UUID]] = None
22
+
23
+ def serialize(
24
+ self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **kwargs
25
+ ) -> JsonObject:
26
+ node = self._node
27
+ node_id = self.node_id
28
+
29
+ code = read_file_from_path(raise_if_descriptor(node.filepath))
30
+ code_node_input = create_node_input(
31
+ node_id=node_id,
32
+ input_name="code",
33
+ value=code,
34
+ display_context=display_context,
35
+ input_id=self.code_input_id,
36
+ )
37
+ runtime_node_input = create_node_input(
38
+ node_id=node_id,
39
+ input_name="runtime",
40
+ value=node.runtime,
41
+ display_context=display_context,
42
+ input_id=self.runtime_input_id,
43
+ )
44
+ inputs = [code_node_input, runtime_node_input]
45
+
46
+ packages = raise_if_descriptor(node.packages)
47
+
48
+ _, output_display = display_context.node_output_displays[node.Outputs.result]
49
+ _, log_output_display = display_context.node_output_displays[node.Outputs.log]
50
+
51
+ output_type = primitive_type_to_vellum_variable_type(node.get_output_type())
52
+
53
+ return {
54
+ "id": str(node_id),
55
+ "type": "CODE_EXECUTION",
56
+ "inputs": [input.dict() for input in inputs],
57
+ "data": {
58
+ "label": self.label,
59
+ "error_output_id": str(error_output_id) if error_output_id else None,
60
+ "source_handle_id": str(self.get_source_handle_id(display_context.port_displays)),
61
+ "target_handle_id": str(self.get_target_handle_id()),
62
+ "code_input_id": str(self.code_input_id) if self.code_input_id else code_node_input.id,
63
+ "runtime_input_id": str(self.runtime_input_id) if self.runtime_input_id else runtime_node_input.id,
64
+ "output_type": output_type,
65
+ "packages": [package.dict() for package in packages] if packages is not None else [],
66
+ "output_id": str(self.output_id) if self.output_id else str(output_display.id),
67
+ "log_output_id": str(self.log_output_id) if self.log_output_id else str(log_output_display.id),
68
+ },
69
+ "display_data": self.get_display_data().dict(),
70
+ "definition": self.get_definition().dict(),
71
+ }
@@ -0,0 +1,217 @@
1
+ from dataclasses import dataclass
2
+ from uuid import UUID
3
+ from typing import Any, ClassVar, Dict, Generic, List, Optional, TypeVar
4
+
5
+ from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
6
+ from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
7
+ from vellum_ee.workflows.display.types import WorkflowDisplayContext
8
+ from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
9
+ from vellum_ee.workflows.display.vellum import NodeInput
10
+ from vellum.workflows.descriptors.base import BaseDescriptor
11
+ from vellum.workflows.expressions.and_ import AndExpression
12
+ from vellum.workflows.expressions.begins_with import BeginsWithExpression
13
+ from vellum.workflows.expressions.between import BetweenExpression
14
+ from vellum.workflows.expressions.contains import ContainsExpression
15
+ from vellum.workflows.expressions.does_not_begin_with import DoesNotBeginWithExpression
16
+ from vellum.workflows.expressions.does_not_contain import DoesNotContainExpression
17
+ from vellum.workflows.expressions.does_not_end_with import DoesNotEndWithExpression
18
+ from vellum.workflows.expressions.does_not_equal import DoesNotEqualExpression
19
+ from vellum.workflows.expressions.ends_with import EndsWithExpression
20
+ from vellum.workflows.expressions.equals import EqualsExpression
21
+ from vellum.workflows.expressions.greater_than import GreaterThanExpression
22
+ from vellum.workflows.expressions.greater_than_or_equal_to import GreaterThanOrEqualToExpression
23
+ from vellum.workflows.expressions.in_ import InExpression
24
+ from vellum.workflows.expressions.is_not_null import IsNotNullExpression
25
+ from vellum.workflows.expressions.is_null import IsNullExpression
26
+ from vellum.workflows.expressions.less_than import LessThanExpression
27
+ from vellum.workflows.expressions.less_than_or_equal_to import LessThanOrEqualToExpression
28
+ from vellum.workflows.expressions.not_between import NotBetweenExpression
29
+ from vellum.workflows.expressions.not_in import NotInExpression
30
+ from vellum.workflows.expressions.or_ import OrExpression
31
+ from vellum.workflows.nodes.displayable import ConditionalNode
32
+ from vellum.workflows.types.core import JsonObject
33
+
34
+ _ConditionalNodeType = TypeVar("_ConditionalNodeType", bound=ConditionalNode)
35
+
36
+
37
+ @dataclass
38
+ class RuleIdMap:
39
+ id: UUID
40
+ lhs: Optional["RuleIdMap"]
41
+ rhs: Optional["RuleIdMap"]
42
+
43
+
44
+ class BaseConditionalNodeDisplay(BaseNodeVellumDisplay[_ConditionalNodeType], Generic[_ConditionalNodeType]):
45
+ source_handle_ids: ClassVar[Dict[int, UUID]]
46
+ rule_ids: ClassVar[List[RuleIdMap]]
47
+
48
+ def serialize(self, display_context: WorkflowDisplayContext, **kwargs: Any) -> JsonObject:
49
+ node = self._node
50
+ node_id = self.node_id
51
+
52
+ node_inputs: List[NodeInput] = []
53
+ source_handle_ids = self._get_source_handle_ids() or {}
54
+
55
+ def serialize_rule(
56
+ descriptor: BaseDescriptor, path: List[int], rule_id_map: Optional[RuleIdMap]
57
+ ) -> Dict[str, Any]:
58
+ rule_id = (
59
+ str(rule_id_map.id)
60
+ if rule_id_map is not None
61
+ else str(uuid4_from_hash(f"{node_id}|rule|{','.join(str(p) for p in path)}"))
62
+ )
63
+ field_node_input_id = None
64
+ value_node_input_id = None
65
+
66
+ # Recursive step: Keep recursing until we hit the other descriptors
67
+ if isinstance(descriptor, (AndExpression, OrExpression)):
68
+ combinator = "AND" if isinstance(descriptor, AndExpression) else "OR"
69
+
70
+ lhs = serialize_rule(descriptor._lhs, path + [0], rule_id_map.lhs if rule_id_map else None)
71
+ rhs = serialize_rule(descriptor._rhs, path + [1], rule_id_map.rhs if rule_id_map else None)
72
+ rules = [lhs, rhs]
73
+
74
+ return {
75
+ "id": rule_id,
76
+ "rules": rules,
77
+ "combinator": combinator,
78
+ "negated": False,
79
+ "field_node_input_id": None,
80
+ "operator": None,
81
+ "value_node_input_id": None,
82
+ }
83
+
84
+ # Base cases for other descriptors
85
+ elif isinstance(descriptor, (IsNullExpression, IsNotNullExpression)):
86
+ expression_node_input = create_node_input(
87
+ node_id, f"{rule_id}.field", descriptor._expression, display_context, None
88
+ )
89
+ node_inputs.append(expression_node_input)
90
+ field_node_input_id = expression_node_input.id
91
+ operator = self._convert_descriptor_to_operator(descriptor)
92
+
93
+ elif isinstance(descriptor, (BetweenExpression, NotBetweenExpression)):
94
+ field_node_input = create_node_input(
95
+ node_id, f"{rule_id}.field", descriptor._value, display_context, None
96
+ )
97
+ value_node_input = create_node_input(
98
+ node_id, f"{rule_id}.value", f"{descriptor._start},{descriptor._end}", display_context, None
99
+ )
100
+ node_inputs.extend([field_node_input, value_node_input])
101
+ operator = self._convert_descriptor_to_operator(descriptor)
102
+ field_node_input_id = field_node_input.id
103
+ value_node_input_id = value_node_input.id
104
+
105
+ else:
106
+ lhs = descriptor._lhs # type: ignore[attr-defined]
107
+ rhs = descriptor._rhs # type: ignore[attr-defined]
108
+
109
+ lhs_node_input = create_node_input(node_id, f"{rule_id}.field", lhs, display_context, None)
110
+ node_inputs.append(lhs_node_input)
111
+
112
+ if descriptor._rhs is not None: # type: ignore[attr-defined]
113
+ rhs_node_input = create_node_input(node_id, f"{rule_id}.value", rhs, display_context, None)
114
+ node_inputs.append(rhs_node_input)
115
+ value_node_input_id = rhs_node_input.id
116
+
117
+ operator = self._convert_descriptor_to_operator(descriptor)
118
+ field_node_input_id = lhs_node_input.id
119
+
120
+ return {
121
+ "id": rule_id,
122
+ "rules": None,
123
+ "combinator": None,
124
+ "negated": False,
125
+ "field_node_input_id": field_node_input_id,
126
+ "operator": operator,
127
+ "value_node_input_id": value_node_input_id,
128
+ }
129
+
130
+ conditions = []
131
+ for idx, port in enumerate(node.Ports):
132
+ if port._condition is None or port._condition_type is None:
133
+ continue
134
+
135
+ condition_id = str(uuid4_from_hash(f"{node_id}|conditions|{idx}"))
136
+ source_handle_id = str(source_handle_ids.get(idx) or uuid4_from_hash(f"{node_id}|handles|{idx}"))
137
+
138
+ rule_ids = self._get_rule_ids()
139
+ condition_rule = serialize_rule(port._condition, [idx], rule_ids[idx] if len(rule_ids) > idx else None)
140
+ rules = condition_rule["rules"] if condition_rule["rules"] else [condition_rule]
141
+
142
+ conditions.append(
143
+ {
144
+ "id": condition_id,
145
+ "type": port._condition_type.value,
146
+ "source_handle_id": source_handle_id,
147
+ "data": {
148
+ "id": str(uuid4_from_hash(f"{condition_id}|rule_group")),
149
+ "rules": rules,
150
+ "combinator": "AND",
151
+ "negated": False,
152
+ "field_node_input_id": None,
153
+ "operator": None,
154
+ "value_node_input_id": None,
155
+ },
156
+ }
157
+ )
158
+
159
+ return {
160
+ "id": str(node_id),
161
+ "type": "CONDITIONAL",
162
+ "inputs": [node_input.dict() for node_input in node_inputs],
163
+ "data": {
164
+ "label": self.label,
165
+ "target_handle_id": str(self.get_target_handle_id()),
166
+ "conditions": conditions, # type: ignore
167
+ "version": "2",
168
+ },
169
+ "display_data": self.get_display_data().dict(),
170
+ "definition": self.get_definition().dict(),
171
+ }
172
+
173
+ def _convert_descriptor_to_operator(self, descriptor: BaseDescriptor) -> str:
174
+ if isinstance(descriptor, EqualsExpression):
175
+ return "="
176
+ elif isinstance(descriptor, DoesNotEqualExpression):
177
+ return "!="
178
+ elif isinstance(descriptor, LessThanExpression):
179
+ return "<"
180
+ elif isinstance(descriptor, GreaterThanExpression):
181
+ return ">"
182
+ elif isinstance(descriptor, LessThanOrEqualToExpression):
183
+ return "<="
184
+ elif isinstance(descriptor, GreaterThanOrEqualToExpression):
185
+ return ">="
186
+ elif isinstance(descriptor, ContainsExpression):
187
+ return "contains"
188
+ elif isinstance(descriptor, BeginsWithExpression):
189
+ return "beginsWith"
190
+ elif isinstance(descriptor, EndsWithExpression):
191
+ return "endsWith"
192
+ elif isinstance(descriptor, DoesNotContainExpression):
193
+ return "doesNotContain"
194
+ elif isinstance(descriptor, DoesNotBeginWithExpression):
195
+ return "doesNotBeginWith"
196
+ elif isinstance(descriptor, DoesNotEndWithExpression):
197
+ return "doesNotEndWith"
198
+ elif isinstance(descriptor, IsNullExpression):
199
+ return "null"
200
+ elif isinstance(descriptor, IsNotNullExpression):
201
+ return "notNull"
202
+ elif isinstance(descriptor, InExpression):
203
+ return "in"
204
+ elif isinstance(descriptor, NotInExpression):
205
+ return "notIn"
206
+ elif isinstance(descriptor, BetweenExpression):
207
+ return "between"
208
+ elif isinstance(descriptor, NotBetweenExpression):
209
+ return "notBetween"
210
+ else:
211
+ raise ValueError(f"Unsupported descriptor type: {descriptor}")
212
+
213
+ def _get_source_handle_ids(self) -> Dict[int, UUID]:
214
+ return self._get_explicit_node_display_attr("source_handle_ids", Dict[int, UUID]) or {}
215
+
216
+ def _get_rule_ids(self) -> List[RuleIdMap]:
217
+ return self._get_explicit_node_display_attr("rule_ids", List[RuleIdMap]) or []
@@ -0,0 +1,61 @@
1
+ from uuid import UUID
2
+ from typing import Any, ClassVar, Generic, Optional, TypeVar
3
+
4
+ from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
5
+ from vellum_ee.workflows.display.nodes.utils import to_kebab_case
6
+ from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
7
+ from vellum_ee.workflows.display.types import WorkflowDisplayContext
8
+ from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
9
+ from vellum_ee.workflows.display.utils.vellum import infer_vellum_variable_type
10
+ from vellum.workflows.nodes.displayable.final_output_node import FinalOutputNode
11
+ from vellum.workflows.types.core import JsonObject
12
+
13
+ _FinalOutputNodeType = TypeVar("_FinalOutputNodeType", bound=FinalOutputNode)
14
+
15
+
16
+ class BaseFinalOutputNodeDisplay(BaseNodeVellumDisplay[_FinalOutputNodeType], Generic[_FinalOutputNodeType]):
17
+ output_id: ClassVar[Optional[UUID]] = None
18
+ output_name: ClassVar[Optional[str]] = None
19
+ node_input_id: ClassVar[Optional[UUID]] = None
20
+
21
+ def serialize(self, display_context: WorkflowDisplayContext, **kwargs: Any) -> JsonObject:
22
+ node = self._node
23
+ node_id = self.node_id
24
+
25
+ node_input = create_node_input(
26
+ node_id,
27
+ "node_input",
28
+ # Get the pointer that the Terminal Node's output is referencing
29
+ node.Outputs.value.instance,
30
+ display_context,
31
+ self._get_node_input_id(),
32
+ )
33
+ inferred_type = infer_vellum_variable_type(node.Outputs.value)
34
+
35
+ return {
36
+ "id": str(node_id),
37
+ "type": "TERMINAL",
38
+ "data": {
39
+ "label": self.label,
40
+ "name": self._get_output_name(),
41
+ "target_handle_id": str(self.get_target_handle_id()),
42
+ "output_id": str(self._get_output_id()),
43
+ "output_type": inferred_type,
44
+ "node_input_id": str(node_input.id),
45
+ },
46
+ "inputs": [node_input.dict()],
47
+ "display_data": self.get_display_data().dict(),
48
+ "definition": self.get_definition().dict(),
49
+ }
50
+
51
+ def _get_output_id(self) -> UUID:
52
+ explicit_value = self._get_explicit_node_display_attr("output_id", UUID)
53
+ return explicit_value if explicit_value else uuid4_from_hash(f"{self.node_id}|output_id")
54
+
55
+ def _get_output_name(self) -> str:
56
+ explicit_value = self._get_explicit_node_display_attr("output_name", str)
57
+ return explicit_value if explicit_value else to_kebab_case(self._node.__name__)
58
+
59
+ def _get_node_input_id(self) -> UUID:
60
+ explicit_value = self._get_explicit_node_display_attr("node_input_id", UUID)
61
+ return explicit_value if explicit_value else uuid4_from_hash(f"{self.node_id}|node_input_id")
@@ -0,0 +1,49 @@
1
+ from uuid import UUID
2
+ from typing import Any, ClassVar, Dict, Generic, Optional, TypeVar
3
+
4
+ from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
5
+ from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
6
+ from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
7
+ from vellum_ee.workflows.display.types import WorkflowDisplayContext
8
+ from vellum.workflows.nodes import GuardrailNode
9
+ from vellum.workflows.types.core import JsonObject
10
+
11
+ _GuardrailNodeType = TypeVar("_GuardrailNodeType", bound=GuardrailNode)
12
+
13
+
14
+ class BaseGuardrailNodeDisplay(BaseNodeVellumDisplay[_GuardrailNodeType], Generic[_GuardrailNodeType]):
15
+ metric_input_ids_by_name: ClassVar[Dict[str, UUID]] = {}
16
+
17
+ def serialize(
18
+ self, display_context: WorkflowDisplayContext, error_output_id: Optional[UUID] = None, **kwargs: Any
19
+ ) -> JsonObject:
20
+ node = self._node
21
+ node_id = self.node_id
22
+
23
+ metric_inputs = raise_if_descriptor(node.metric_inputs)
24
+ node_inputs = [
25
+ create_node_input(
26
+ node_id=node_id,
27
+ input_name=variable_name,
28
+ value=variable_value,
29
+ display_context=display_context,
30
+ input_id=self.metric_input_ids_by_name.get(variable_name),
31
+ )
32
+ for variable_name, variable_value in metric_inputs.items()
33
+ ]
34
+
35
+ return {
36
+ "id": str(node_id),
37
+ "type": "METRIC",
38
+ "inputs": [node_input.dict() for node_input in node_inputs],
39
+ "data": {
40
+ "label": self.label,
41
+ "source_handle_id": str(self.get_source_handle_id(display_context.port_displays)),
42
+ "target_handle_id": str(self.get_target_handle_id()),
43
+ "error_output_id": str(error_output_id) if error_output_id else None,
44
+ "metric_definition_id": str(raise_if_descriptor(node.metric_definition)),
45
+ "release_tag": raise_if_descriptor(node.release_tag),
46
+ },
47
+ "display_data": self.get_display_data().dict(),
48
+ "definition": self.get_definition().dict(),
49
+ }