vellum-ai 0.9.16rc2__py3-none-any.whl → 0.10.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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.10.0.dist-info}/METADATA +2 -1
  179. {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.10.0.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.10.0.dist-info}/LICENSE +0 -0
  244. {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.10.0.dist-info}/WHEEL +0 -0
  245. {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.10.0.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)