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,357 @@
1
+ from dataclasses import dataclass, field
2
+ from enum import Enum
3
+ from uuid import UUID
4
+ from typing import Any, List, Literal, Optional, Union
5
+
6
+ from pydantic import Field
7
+
8
+ from vellum import ChatMessage, PromptParameters, SearchResult, SearchResultRequest, VellumVariable, VellumVariableType
9
+ from vellum.core import UniversalBaseModel
10
+
11
+ from vellum_ee.workflows.display.base import (
12
+ EdgeDisplay,
13
+ EdgeDisplayOverrides,
14
+ EntrypointDisplay,
15
+ EntrypointDisplayOverrides,
16
+ WorkflowInputsDisplay,
17
+ WorkflowInputsDisplayOverrides,
18
+ WorkflowMetaDisplay,
19
+ WorkflowMetaDisplayOverrides,
20
+ WorkflowOutputDisplay,
21
+ WorkflowOutputDisplayOverrides,
22
+ )
23
+
24
+
25
+ class NodeDisplayPosition(UniversalBaseModel):
26
+ x: float = 0.0
27
+ y: float = 0.0
28
+
29
+
30
+ class NodeDisplayComment(UniversalBaseModel):
31
+ value: Optional[str] = None
32
+ expanded: Optional[bool] = None
33
+
34
+
35
+ class NodeDisplayData(UniversalBaseModel):
36
+ position: NodeDisplayPosition = Field(default_factory=NodeDisplayPosition)
37
+ width: Optional[int] = None
38
+ height: Optional[int] = None
39
+ comment: Optional[NodeDisplayComment] = None
40
+
41
+
42
+ class CodeResourceDefinition(UniversalBaseModel):
43
+ name: str
44
+ module: List[str]
45
+
46
+
47
+ class NodeDefinition(UniversalBaseModel):
48
+ name: str
49
+ module: List[str]
50
+ bases: List[CodeResourceDefinition]
51
+
52
+
53
+ class WorkflowDisplayDataViewport(UniversalBaseModel):
54
+ x: float = 0.0
55
+ y: float = 0.0
56
+ zoom: float = 1.0
57
+
58
+
59
+ class WorkflowDisplayData(UniversalBaseModel):
60
+ viewport: WorkflowDisplayDataViewport = Field(default_factory=WorkflowDisplayDataViewport)
61
+
62
+
63
+ @dataclass
64
+ class WorkflowMetaVellumDisplayOverrides(WorkflowMetaDisplay, WorkflowMetaDisplayOverrides):
65
+ entrypoint_node_id: UUID
66
+ entrypoint_node_source_handle_id: UUID
67
+ entrypoint_node_display: NodeDisplayData
68
+ display_data: WorkflowDisplayData = field(default_factory=WorkflowDisplayData)
69
+
70
+
71
+ @dataclass
72
+ class WorkflowMetaVellumDisplay(WorkflowMetaVellumDisplayOverrides):
73
+ pass
74
+
75
+
76
+ @dataclass
77
+ class WorkflowInputsVellumDisplayOverrides(WorkflowInputsDisplay, WorkflowInputsDisplayOverrides):
78
+ pass
79
+
80
+
81
+ @dataclass
82
+ class WorkflowInputsVellumDisplay(WorkflowInputsVellumDisplayOverrides):
83
+ pass
84
+
85
+
86
+ @dataclass
87
+ class EdgeVellumDisplayOverrides(EdgeDisplay, EdgeDisplayOverrides):
88
+ pass
89
+
90
+
91
+ @dataclass
92
+ class EdgeVellumDisplay(EdgeVellumDisplayOverrides):
93
+ source_node_id: UUID
94
+ source_handle_id: UUID
95
+ target_node_id: UUID
96
+ target_handle_id: UUID
97
+ type: Literal["DEFAULT"] = "DEFAULT"
98
+
99
+
100
+ @dataclass
101
+ class EntrypointVellumDisplayOverrides(EntrypointDisplay, EntrypointDisplayOverrides):
102
+ edge_display: EdgeVellumDisplayOverrides
103
+
104
+
105
+ @dataclass
106
+ class EntrypointVellumDisplay(EntrypointVellumDisplayOverrides):
107
+ edge_display: EdgeVellumDisplay
108
+
109
+
110
+ @dataclass
111
+ class WorkflowOutputVellumDisplayOverrides(WorkflowOutputDisplay, WorkflowOutputDisplayOverrides):
112
+ name: str
113
+ label: str
114
+ node_id: UUID
115
+ node_input_id: UUID
116
+ target_handle_id: UUID
117
+ display_data: NodeDisplayData
118
+ edge_id: UUID
119
+ # source_node_id: Optional[UUID]
120
+ # source_handle_id: Optional[UUID]
121
+
122
+
123
+ @dataclass
124
+ class WorkflowOutputVellumDisplay(WorkflowOutputVellumDisplayOverrides):
125
+ pass
126
+
127
+
128
+ class WorkflowNodeType(str, Enum):
129
+ PROMPT = "PROMPT"
130
+ TEMPLATING = "TEMPLATING"
131
+ NOTE = "NOTE"
132
+ CODE_EXECUTION = "CODE_EXECUTION"
133
+ METRIC = "METRIC"
134
+ SEARCH = "SEARCH"
135
+ WEBHOOK = "WEBHOOK"
136
+ MERGE = "MERGE"
137
+ CONDITIONAL = "CONDITIONAL"
138
+ API = "API"
139
+ ENTRYPOINT = "ENTRYPOINT"
140
+ TERMINAL = "TERMINAL"
141
+ SUBWORKFLOW = "SUBWORKFLOW"
142
+ MAP = "MAP"
143
+ ERROR = "ERROR"
144
+
145
+
146
+ class StringVellumValue(UniversalBaseModel):
147
+ type: Literal["STRING"] = "STRING"
148
+ value: str
149
+
150
+
151
+ class NumberVellumValue(UniversalBaseModel):
152
+ type: Literal["NUMBER"] = "NUMBER"
153
+ value: Union[int, float]
154
+
155
+
156
+ class ChatHistoryVellumValue(UniversalBaseModel):
157
+ type: Literal["CHAT_HISTORY"] = "CHAT_HISTORY"
158
+ value: Union[List[ChatMessage], List[ChatMessage]]
159
+
160
+
161
+ class SearchResultsVellumValue(UniversalBaseModel):
162
+ type: Literal["SEARCH_RESULTS"] = "SEARCH_RESULTS"
163
+ value: Union[List[SearchResultRequest], List[SearchResult]]
164
+
165
+
166
+ class JsonVellumValue(UniversalBaseModel):
167
+ type: Literal["JSON"] = "JSON"
168
+ value: Optional[Any] = None
169
+
170
+
171
+ VellumValue = Union[
172
+ StringVellumValue,
173
+ NumberVellumValue,
174
+ ChatHistoryVellumValue,
175
+ SearchResultsVellumValue,
176
+ JsonVellumValue,
177
+ ]
178
+
179
+
180
+ class ConstantValuePointer(UniversalBaseModel):
181
+ type: Literal["CONSTANT_VALUE"] = "CONSTANT_VALUE"
182
+ data: VellumValue
183
+
184
+
185
+ class NodeOutputData(UniversalBaseModel):
186
+ node_id: str
187
+ output_id: str
188
+
189
+
190
+ class NodeOutputPointer(UniversalBaseModel):
191
+ type: Literal["NODE_OUTPUT"] = "NODE_OUTPUT"
192
+ data: NodeOutputData
193
+
194
+
195
+ class InputVariableData(UniversalBaseModel):
196
+ input_variable_id: str
197
+
198
+
199
+ class InputVariablePointer(UniversalBaseModel):
200
+ type: Literal["INPUT_VARIABLE"] = "INPUT_VARIABLE"
201
+ data: InputVariableData
202
+
203
+
204
+ class WorkspaceSecretData(UniversalBaseModel):
205
+ type: VellumVariableType
206
+ workspace_secret_id: str
207
+
208
+
209
+ class WorkspaceSecretPointer(UniversalBaseModel):
210
+ type: Literal["WORKSPACE_SECRET"] = "WORKSPACE_SECRET"
211
+ data: WorkspaceSecretData
212
+
213
+
214
+ NodeInputValuePointerRule = Union[
215
+ NodeOutputPointer,
216
+ InputVariablePointer,
217
+ ConstantValuePointer,
218
+ WorkspaceSecretPointer,
219
+ ]
220
+
221
+
222
+ class NodeInputValuePointer(UniversalBaseModel):
223
+ rules: List[NodeInputValuePointerRule]
224
+ combinator: Literal["OR"] = "OR"
225
+
226
+
227
+ class NodeInput(UniversalBaseModel):
228
+ id: str
229
+ key: str
230
+ value: NodeInputValuePointer
231
+
232
+
233
+ class BaseWorkflowNode(UniversalBaseModel):
234
+ id: str
235
+ inputs: List[NodeInput]
236
+ type: str
237
+ display_data: Optional[NodeDisplayData] = None
238
+ definition: Optional[NodeDefinition] = None
239
+
240
+
241
+ class EntrypointNodeData(UniversalBaseModel):
242
+ source_handle_id: str
243
+
244
+
245
+ class EntrypointNode(BaseWorkflowNode):
246
+ type: Literal[WorkflowNodeType.ENTRYPOINT] = WorkflowNodeType.ENTRYPOINT
247
+ data: EntrypointNodeData
248
+
249
+
250
+ class PromptTemplateBlockData(UniversalBaseModel):
251
+ version: Literal[1] = 1
252
+ # blocks: List[PromptBlockRequest]
253
+
254
+
255
+ class PromptVersionExecConfig(UniversalBaseModel):
256
+ parameters: PromptParameters
257
+ input_variables: List[VellumVariable]
258
+ prompt_template_block_data: PromptTemplateBlockData
259
+
260
+
261
+ class BasePromptNodeData(UniversalBaseModel):
262
+ label: str
263
+ output_id: str
264
+ error_output_id: Optional[str] = None
265
+ array_output_id: str
266
+ source_handle_id: str
267
+ target_handle_id: str
268
+
269
+
270
+ class InlinePromptNodeData(BasePromptNodeData):
271
+ variant: Literal["INLINE"] = "INLINE"
272
+ exec_config: PromptVersionExecConfig
273
+ ml_model_name: str
274
+
275
+
276
+ class DeploymentPromptNodeData(BasePromptNodeData):
277
+ variant: Literal["DEPLOYMENT"] = "DEPLOYMENT"
278
+ deployment_id: str
279
+ release_tag: str
280
+
281
+
282
+ PromptNodeData = Union[
283
+ InlinePromptNodeData,
284
+ DeploymentPromptNodeData,
285
+ ]
286
+
287
+
288
+ class PromptNode(BaseWorkflowNode):
289
+ type: Literal[WorkflowNodeType.PROMPT] = WorkflowNodeType.PROMPT
290
+ data: PromptNodeData
291
+
292
+
293
+ class SearchNodeData(UniversalBaseModel):
294
+ label: str
295
+
296
+ results_output_id: str
297
+ text_output_id: str
298
+ error_output_id: Optional[str] = None
299
+
300
+ source_handle_id: str
301
+ target_handle_id: str
302
+
303
+ query_node_input_id: str
304
+ document_index_node_input_id: str
305
+ weights_node_input_id: str
306
+ limit_node_input_id: str
307
+ separator_node_input_id: str
308
+ result_merging_enabled_node_input_id: str
309
+ external_id_filters_node_input_id: str
310
+ metadata_filters_node_input_id: str
311
+
312
+
313
+ class SearchNode(BaseWorkflowNode):
314
+ type: Literal[WorkflowNodeType.SEARCH] = WorkflowNodeType.SEARCH
315
+ data: SearchNodeData
316
+
317
+
318
+ class FinalOutputNodeData(UniversalBaseModel):
319
+ label: str
320
+ name: str
321
+ target_handle_id: str
322
+ output_id: str
323
+ output_type: VellumVariableType
324
+ node_input_id: str
325
+
326
+
327
+ class FinalOutputNode(BaseWorkflowNode):
328
+ type: Literal[WorkflowNodeType.TERMINAL] = WorkflowNodeType.TERMINAL
329
+ data: FinalOutputNodeData
330
+
331
+
332
+ WorkflowNode = Union[
333
+ EntrypointNode,
334
+ PromptNode,
335
+ SearchNode,
336
+ FinalOutputNode,
337
+ ]
338
+
339
+
340
+ class WorkflowEdge(UniversalBaseModel):
341
+ id: str
342
+ source_node_id: str
343
+ source_handle_id: str
344
+ target_node_id: str
345
+ target_handle_id: str
346
+
347
+
348
+ class WorkflowRawData(UniversalBaseModel):
349
+ nodes: List[WorkflowNode]
350
+ edges: List[WorkflowEdge]
351
+ display_data: Optional[WorkflowDisplayData] = None
352
+
353
+
354
+ class WorkflowVersionExecConfig(UniversalBaseModel):
355
+ workflow_raw_data: WorkflowRawData
356
+ input_variables: List[VellumVariable]
357
+ output_variables: List[VellumVariable]
@@ -0,0 +1,5 @@
1
+ # flake8: noqa: F401, F403
2
+
3
+ # These must be imported to register the classes in the registry
4
+ from .base_workflow_display import BaseWorkflowDisplay
5
+ from .vellum_workflow_display import VellumWorkflowDisplay
@@ -0,0 +1,302 @@
1
+ from abc import abstractmethod
2
+ from copy import deepcopy
3
+ from functools import cached_property
4
+ import logging
5
+ from uuid import UUID
6
+ from typing import Any, Dict, Generic, Optional, Tuple, Type, get_args
7
+
8
+ from vellum_ee.workflows.display.base import (
9
+ EdgeDisplayOverridesType,
10
+ EdgeDisplayType,
11
+ EntrypointDisplayOverridesType,
12
+ EntrypointDisplayType,
13
+ WorkflowInputsDisplayOverridesType,
14
+ WorkflowInputsDisplayType,
15
+ WorkflowMetaDisplayOverridesType,
16
+ WorkflowMetaDisplayType,
17
+ WorkflowOutputDisplayOverridesType,
18
+ WorkflowOutputDisplayType,
19
+ )
20
+ from vellum_ee.workflows.display.nodes.get_node_display_class import get_node_display_class
21
+ from vellum_ee.workflows.display.nodes.types import NodeOutputDisplay, PortDisplay, PortDisplayOverrides
22
+ from vellum_ee.workflows.display.types import NodeDisplayType, WorkflowDisplayContext
23
+ from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
24
+ from vellum.workflows.descriptors.base import BaseDescriptor
25
+ from vellum.workflows.edges import Edge
26
+ from vellum.workflows.expressions.coalesce_expression import CoalesceExpression
27
+ from vellum.workflows.nodes.bases import BaseNode
28
+ from vellum.workflows.nodes.utils import get_wrapped_node, has_wrapped_node
29
+ from vellum.workflows.ports import Port
30
+ from vellum.workflows.references import OutputReference, WorkflowInputReference
31
+ from vellum.workflows.types.core import JsonObject
32
+ from vellum.workflows.types.generics import WorkflowType
33
+
34
+ logger = logging.getLogger(__name__)
35
+
36
+
37
+ class BaseWorkflowDisplay(
38
+ Generic[
39
+ WorkflowType,
40
+ WorkflowMetaDisplayType,
41
+ WorkflowMetaDisplayOverridesType,
42
+ WorkflowInputsDisplayType,
43
+ WorkflowInputsDisplayOverridesType,
44
+ NodeDisplayType,
45
+ EntrypointDisplayType,
46
+ EntrypointDisplayOverridesType,
47
+ EdgeDisplayType,
48
+ EdgeDisplayOverridesType,
49
+ WorkflowOutputDisplayType,
50
+ WorkflowOutputDisplayOverridesType,
51
+ ]
52
+ ):
53
+ # Used to specify the display data for a workflow.
54
+ workflow_display: Optional[WorkflowMetaDisplayOverridesType] = None
55
+
56
+ # Used to explicitly specify display data for a workflow's inputs.
57
+ inputs_display: Dict[WorkflowInputReference, WorkflowInputsDisplayOverridesType] = {}
58
+
59
+ # Used to explicitly specify display data for a workflow's entrypoints.
60
+ entrypoint_displays: Dict[Type[BaseNode], EntrypointDisplayOverridesType] = {}
61
+
62
+ # Used to explicitly specify display data for a workflow's outputs.
63
+ output_displays: Dict[BaseDescriptor, WorkflowOutputDisplayOverridesType] = {}
64
+
65
+ # Used to explicitly specify display data for a workflow's edges.
66
+ edge_displays: Dict[Tuple[Port, Type[BaseNode]], EdgeDisplayOverridesType] = {}
67
+
68
+ # Used to explicitly specify display data for a workflow's ports.
69
+ port_displays: Dict[Port, PortDisplayOverrides] = {}
70
+
71
+ # Used to store the mapping between workflows and their display classes
72
+ _workflow_display_registry: Dict[Type[WorkflowType], Type["BaseWorkflowDisplay"]] = {}
73
+
74
+ def __init__(
75
+ self,
76
+ workflow: Type[WorkflowType],
77
+ *,
78
+ parent_display_context: Optional[
79
+ WorkflowDisplayContext[
80
+ WorkflowMetaDisplayType,
81
+ WorkflowInputsDisplayType,
82
+ NodeDisplayType,
83
+ EntrypointDisplayType,
84
+ WorkflowOutputDisplayType,
85
+ EdgeDisplayType,
86
+ ]
87
+ ] = None,
88
+ ):
89
+ self._workflow = workflow
90
+ self._parent_display_context = parent_display_context
91
+
92
+ @abstractmethod
93
+ def serialize(self, raise_errors: bool = True) -> JsonObject:
94
+ pass
95
+
96
+ @classmethod
97
+ def get_from_workflow_display_registry(cls, workflow_class: Type[WorkflowType]) -> Type["BaseWorkflowDisplay"]:
98
+ try:
99
+ return cls._workflow_display_registry[workflow_class]
100
+ except KeyError:
101
+ return cls._workflow_display_registry[WorkflowType] # type: ignore [misc]
102
+
103
+ @cached_property
104
+ def workflow_id(self) -> UUID:
105
+ """Can be overridden as a class attribute to specify a custom workflow id."""
106
+ return uuid4_from_hash(self._workflow.__qualname__)
107
+
108
+ @property
109
+ @abstractmethod
110
+ def node_display_base_class(self) -> Type[NodeDisplayType]:
111
+ pass
112
+
113
+ def _enrich_node_output_displays(
114
+ self,
115
+ node: Type[BaseNode],
116
+ node_display: NodeDisplayType,
117
+ node_output_displays: Dict[OutputReference, Tuple[Type[BaseNode], NodeOutputDisplay]],
118
+ ):
119
+ """This method recursively adds nodes wrapped in decorators to the node_output_displays dictionary."""
120
+
121
+ for node_output in node.Outputs:
122
+ if node_output in node_output_displays:
123
+ continue
124
+
125
+ if has_wrapped_node(node):
126
+ inner_node = get_wrapped_node(node)
127
+ if inner_node._is_wrapped_node:
128
+ inner_node_display = self._get_node_display(inner_node)
129
+ self._enrich_node_output_displays(inner_node, inner_node_display, node_output_displays)
130
+
131
+ node_output_displays[node_output] = node, node_display.get_node_output_display(node_output)
132
+
133
+ def _enrich_node_port_displays(
134
+ self,
135
+ node: Type[BaseNode],
136
+ node_display: NodeDisplayType,
137
+ port_displays: Dict[Port, PortDisplay],
138
+ ):
139
+ """This method recursively adds nodes wrapped in decorators to the port_displays dictionary."""
140
+
141
+ for port in node.Ports:
142
+ if port in port_displays:
143
+ continue
144
+
145
+ if has_wrapped_node(node):
146
+ inner_node = get_wrapped_node(node)
147
+ if inner_node._is_wrapped_node:
148
+ inner_node_display = self._get_node_display(inner_node)
149
+ self._enrich_node_port_displays(inner_node, inner_node_display, port_displays)
150
+
151
+ port_displays[port] = node_display.get_node_port_display(port)
152
+
153
+ def _get_node_display(self, node: Type[BaseNode]) -> NodeDisplayType:
154
+ node_display_class = get_node_display_class(self.node_display_base_class, node)
155
+ node_display = node_display_class(node)
156
+
157
+ if not isinstance(node_display, self.node_display_base_class):
158
+ raise ValueError(f"{node.__name__} must be a subclass of {self.node_display_base_class.__name__}")
159
+
160
+ return node_display
161
+
162
+ @cached_property
163
+ def display_context(
164
+ self,
165
+ ) -> WorkflowDisplayContext[
166
+ WorkflowMetaDisplayType,
167
+ WorkflowInputsDisplayType,
168
+ NodeDisplayType,
169
+ EntrypointDisplayType,
170
+ WorkflowOutputDisplayType,
171
+ EdgeDisplayType,
172
+ ]:
173
+ workflow_display = self._generate_workflow_meta_display()
174
+
175
+ # If we're dealing with a nested workflow, then it should have access to the outputs of all nodes
176
+ node_output_displays: Dict[OutputReference, Tuple[Type[BaseNode], NodeOutputDisplay]] = (
177
+ deepcopy(self._parent_display_context.node_output_displays) if self._parent_display_context else {}
178
+ )
179
+
180
+ node_displays: Dict[Type[BaseNode], NodeDisplayType] = {}
181
+ port_displays: Dict[Port, PortDisplay] = {}
182
+ for node in self._workflow.get_nodes():
183
+ node_display = self._get_node_display(node)
184
+ node_displays[node] = node_display
185
+
186
+ # Nodes wrapped in a decorator need to be in our node display dictionary for later retrieval
187
+ if has_wrapped_node(node):
188
+ inner_node = get_wrapped_node(node)
189
+ inner_node_display = self._get_node_display(inner_node)
190
+
191
+ if inner_node._is_wrapped_node:
192
+ node_displays[inner_node] = inner_node_display
193
+
194
+ self._enrich_node_output_displays(node, node_display, node_output_displays)
195
+ self._enrich_node_port_displays(node, node_display, port_displays)
196
+
197
+ # If we're dealing with a nested workflow, then it should have access to the inputs of its parents.
198
+ workflow_input_displays: Dict[WorkflowInputReference, WorkflowInputsDisplayType] = (
199
+ deepcopy(self._parent_display_context.workflow_input_displays) if self._parent_display_context else {}
200
+ )
201
+ for workflow_input in self._workflow.get_inputs_class():
202
+ if workflow_input in workflow_input_displays:
203
+ continue
204
+
205
+ workflow_input_display_overrides = self.inputs_display.get(workflow_input)
206
+ workflow_input_displays[workflow_input] = self._generate_workflow_input_display(
207
+ workflow_input, overrides=workflow_input_display_overrides
208
+ )
209
+
210
+ entrypoint_displays: Dict[Type[BaseNode], EntrypointDisplayType] = {}
211
+ for entrypoint in self._workflow.get_entrypoints():
212
+ if entrypoint in entrypoint_displays:
213
+ continue
214
+
215
+ entrypoint_display_overrides = self.entrypoint_displays.get(entrypoint)
216
+ entrypoint_displays[entrypoint] = self._generate_entrypoint_display(
217
+ entrypoint, workflow_display, node_displays, overrides=entrypoint_display_overrides
218
+ )
219
+
220
+ edge_displays: Dict[Tuple[Port, Type[BaseNode]], EdgeDisplayType] = {}
221
+ for edge in self._workflow.get_edges():
222
+ if edge in edge_displays:
223
+ continue
224
+
225
+ edge_display_overrides = self.edge_displays.get((edge.from_port, edge.to_node))
226
+ edge_displays[(edge.from_port, edge.to_node)] = self._generate_edge_display(
227
+ edge, node_displays, port_displays, overrides=edge_display_overrides
228
+ )
229
+
230
+ workflow_output_displays: Dict[BaseDescriptor, WorkflowOutputDisplayType] = {}
231
+ for workflow_output in self._workflow.Outputs:
232
+ if workflow_output in workflow_output_displays:
233
+ continue
234
+
235
+ if not isinstance(workflow_output, OutputReference):
236
+ raise ValueError(f"{workflow_output} must be an {OutputReference.__name__}")
237
+
238
+ if not workflow_output.instance or not isinstance(
239
+ workflow_output.instance, (OutputReference, CoalesceExpression)
240
+ ):
241
+ raise ValueError("Expected to find a descriptor instance on the workflow output")
242
+
243
+ workflow_output_display_overrides = self.output_displays.get(workflow_output)
244
+ workflow_output_displays[workflow_output] = self._generate_workflow_output_display(
245
+ workflow_output, overrides=workflow_output_display_overrides
246
+ )
247
+
248
+ return WorkflowDisplayContext(
249
+ workflow_display=workflow_display,
250
+ workflow_input_displays=workflow_input_displays,
251
+ node_displays=node_displays,
252
+ node_output_displays=node_output_displays,
253
+ entrypoint_displays=entrypoint_displays,
254
+ workflow_output_displays=workflow_output_displays,
255
+ edge_displays=edge_displays,
256
+ port_displays=port_displays,
257
+ workflow_display_class=self.__class__,
258
+ )
259
+
260
+ @abstractmethod
261
+ def _generate_workflow_meta_display(self) -> WorkflowMetaDisplayType:
262
+ pass
263
+
264
+ @abstractmethod
265
+ def _generate_workflow_input_display(
266
+ self, workflow_input: WorkflowInputReference, overrides: Optional[WorkflowInputsDisplayOverridesType] = None
267
+ ) -> WorkflowInputsDisplayType:
268
+ pass
269
+
270
+ @abstractmethod
271
+ def _generate_entrypoint_display(
272
+ self,
273
+ entrypoint: Type[BaseNode],
274
+ workflow_display: WorkflowMetaDisplayType,
275
+ node_displays: Dict[Type[BaseNode], NodeDisplayType],
276
+ overrides: Optional[EntrypointDisplayOverridesType] = None,
277
+ ) -> EntrypointDisplayType:
278
+ pass
279
+
280
+ @abstractmethod
281
+ def _generate_workflow_output_display(
282
+ self,
283
+ output: BaseDescriptor,
284
+ overrides: Optional[WorkflowOutputDisplayOverridesType] = None,
285
+ ) -> WorkflowOutputDisplayType:
286
+ pass
287
+
288
+ @abstractmethod
289
+ def _generate_edge_display(
290
+ self,
291
+ edge: Edge,
292
+ node_displays: Dict[Type[BaseNode], NodeDisplayType],
293
+ port_displays: Dict[Port, PortDisplay],
294
+ overrides: Optional[EdgeDisplayOverridesType] = None,
295
+ ) -> EdgeDisplayType:
296
+ pass
297
+
298
+ def __init_subclass__(cls, **kwargs: Any) -> None:
299
+ super().__init_subclass__(**kwargs)
300
+
301
+ workflow_class = get_args(cls.__orig_bases__[0])[0] # type: ignore [attr-defined]
302
+ cls._workflow_display_registry[workflow_class] = cls
@@ -0,0 +1,32 @@
1
+ from typing import Optional, Type
2
+
3
+ from vellum_ee.workflows.display.types import WorkflowDisplayContext, WorkflowDisplayType
4
+ from vellum.workflows.types.generics import WorkflowType
5
+
6
+
7
+ def get_workflow_display(
8
+ *,
9
+ base_display_class: Type[WorkflowDisplayType],
10
+ workflow_class: Type[WorkflowType],
11
+ root_workflow_class: Optional[Type[WorkflowType]] = None,
12
+ parent_display_context: Optional[WorkflowDisplayContext] = None,
13
+ ) -> WorkflowDisplayType:
14
+ try:
15
+ workflow_display_class = base_display_class.get_from_workflow_display_registry(workflow_class)
16
+ except KeyError:
17
+ try:
18
+ return get_workflow_display(
19
+ base_display_class=base_display_class,
20
+ workflow_class=workflow_class.__bases__[0],
21
+ root_workflow_class=workflow_class if root_workflow_class is None else root_workflow_class,
22
+ parent_display_context=parent_display_context,
23
+ )
24
+ except IndexError:
25
+ return base_display_class(workflow_class)
26
+
27
+ if not issubclass(workflow_display_class, base_display_class):
28
+ raise TypeError(
29
+ f"Expected to find a subclass of '{base_display_class.__name__}' for workflow class '{workflow_class.__name__}'" # noqa: E501
30
+ )
31
+
32
+ return workflow_display_class(workflow_class, parent_display_context=parent_display_context)