vellum-ai 0.14.23__py3-none-any.whl → 0.14.25__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 (29) hide show
  1. vellum/client/core/client_wrapper.py +1 -1
  2. vellum/client/types/vellum_sdk_error.py +1 -1
  3. vellum/client/types/workflow_execution_event_error_code.py +1 -0
  4. vellum/plugins/pydantic.py +2 -0
  5. vellum/workflows/nodes/core/inline_subworkflow_node/node.py +6 -0
  6. vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py +27 -0
  7. vellum/workflows/nodes/displayable/guardrail_node/node.py +13 -1
  8. {vellum_ai-0.14.23.dist-info → vellum_ai-0.14.25.dist-info}/METADATA +1 -1
  9. {vellum_ai-0.14.23.dist-info → vellum_ai-0.14.25.dist-info}/RECORD +29 -27
  10. vellum_ee/workflows/display/base.py +29 -14
  11. vellum_ee/workflows/display/editor/__init__.py +7 -0
  12. vellum_ee/workflows/display/editor/types.py +22 -0
  13. vellum_ee/workflows/display/nodes/base_node_display.py +4 -2
  14. vellum_ee/workflows/display/nodes/base_node_vellum_display.py +1 -1
  15. vellum_ee/workflows/display/nodes/vellum/api_node.py +1 -1
  16. vellum_ee/workflows/display/nodes/vellum/search_node.py +2 -1
  17. vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +5 -11
  18. vellum_ee/workflows/display/nodes/vellum/utils.py +3 -4
  19. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py +2 -1
  20. vellum_ee/workflows/display/types.py +19 -16
  21. vellum_ee/workflows/display/utils/expressions.py +6 -2
  22. vellum_ee/workflows/display/utils/vellum.py +59 -13
  23. vellum_ee/workflows/display/vellum.py +29 -100
  24. vellum_ee/workflows/display/workflows/base_workflow_display.py +99 -57
  25. vellum_ee/workflows/display/workflows/tests/test_workflow_display.py +1 -1
  26. vellum_ee/workflows/display/workflows/vellum_workflow_display.py +2 -56
  27. {vellum_ai-0.14.23.dist-info → vellum_ai-0.14.25.dist-info}/LICENSE +0 -0
  28. {vellum_ai-0.14.23.dist-info → vellum_ai-0.14.25.dist-info}/WHEEL +0 -0
  29. {vellum_ai-0.14.23.dist-info → vellum_ai-0.14.25.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,9 @@
1
- from typing import TYPE_CHECKING, Any
1
+ from typing import TYPE_CHECKING, Any, Literal, Optional, Union
2
2
 
3
+ from vellum.client.core.pydantic_utilities import UniversalBaseModel
4
+ from vellum.client.types.array_vellum_value import ArrayVellumValue
3
5
  from vellum.client.types.logical_operator import LogicalOperator
6
+ from vellum.client.types.vellum_value import VellumValue
4
7
  from vellum.client.types.vellum_variable_type import VellumVariableType
5
8
  from vellum.workflows.descriptors.base import BaseDescriptor
6
9
  from vellum.workflows.expressions.and_ import AndExpression
@@ -39,23 +42,66 @@ from vellum.workflows.references.vellum_secret import VellumSecretReference
39
42
  from vellum.workflows.utils.vellum_variables import primitive_type_to_vellum_variable_type
40
43
  from vellum.workflows.vellum_client import create_vellum_client
41
44
  from vellum_ee.workflows.display.utils.expressions import get_child_descriptor
42
- from vellum_ee.workflows.display.vellum import (
43
- ConstantValuePointer,
44
- ExecutionCounterData,
45
- ExecutionCounterPointer,
46
- InputVariableData,
47
- InputVariablePointer,
48
- NodeInputValuePointerRule,
49
- NodeOutputData,
50
- NodeOutputPointer,
51
- WorkspaceSecretData,
52
- WorkspaceSecretPointer,
53
- )
54
45
 
55
46
  if TYPE_CHECKING:
56
47
  from vellum_ee.workflows.display.types import WorkflowDisplayContext
57
48
 
58
49
 
50
+ class ConstantValuePointer(UniversalBaseModel):
51
+ type: Literal["CONSTANT_VALUE"] = "CONSTANT_VALUE"
52
+ data: VellumValue
53
+
54
+
55
+ ArrayVellumValue.model_rebuild()
56
+
57
+
58
+ class NodeOutputData(UniversalBaseModel):
59
+ node_id: str
60
+ output_id: str
61
+
62
+
63
+ class NodeOutputPointer(UniversalBaseModel):
64
+ type: Literal["NODE_OUTPUT"] = "NODE_OUTPUT"
65
+ data: NodeOutputData
66
+
67
+
68
+ class InputVariableData(UniversalBaseModel):
69
+ input_variable_id: str
70
+
71
+
72
+ class InputVariablePointer(UniversalBaseModel):
73
+ type: Literal["INPUT_VARIABLE"] = "INPUT_VARIABLE"
74
+ data: InputVariableData
75
+
76
+
77
+ class WorkspaceSecretData(UniversalBaseModel):
78
+ type: VellumVariableType
79
+ workspace_secret_id: Optional[str] = None
80
+
81
+
82
+ class WorkspaceSecretPointer(UniversalBaseModel):
83
+ type: Literal["WORKSPACE_SECRET"] = "WORKSPACE_SECRET"
84
+ data: WorkspaceSecretData
85
+
86
+
87
+ class ExecutionCounterData(UniversalBaseModel):
88
+ node_id: str
89
+
90
+
91
+ class ExecutionCounterPointer(UniversalBaseModel):
92
+ type: Literal["EXECUTION_COUNTER"] = "EXECUTION_COUNTER"
93
+ data: ExecutionCounterData
94
+
95
+
96
+ NodeInputValuePointerRule = Union[
97
+ NodeOutputPointer,
98
+ InputVariablePointer,
99
+ ConstantValuePointer,
100
+ WorkspaceSecretPointer,
101
+ ExecutionCounterPointer,
102
+ ]
103
+
104
+
59
105
  def infer_vellum_variable_type(value: Any) -> VellumVariableType:
60
106
  inferred_type: VellumVariableType
61
107
 
@@ -1,43 +1,24 @@
1
- from dataclasses import dataclass, field
1
+ from dataclasses import dataclass
2
2
  from uuid import UUID
3
- from typing import List, Literal, Optional, Union
3
+ from typing import List, Literal, Optional
4
4
 
5
- from pydantic import Field
6
-
7
- from vellum import VellumVariableType
8
- from vellum.client.types.array_vellum_value import ArrayVellumValue
9
- from vellum.client.types.vellum_value import VellumValue
10
5
  from vellum.core import UniversalBaseModel
11
6
  from vellum_ee.workflows.display.base import (
12
- EdgeDisplay,
13
7
  EdgeDisplayOverrides,
14
- EntrypointDisplay,
15
8
  EntrypointDisplayOverrides,
16
9
  StateValueDisplay,
17
10
  StateValueDisplayOverrides,
18
11
  WorkflowInputsDisplay,
19
12
  WorkflowInputsDisplayOverrides,
20
- WorkflowMetaDisplay,
21
13
  WorkflowMetaDisplayOverrides,
22
14
  WorkflowOutputDisplayOverrides,
23
15
  )
24
-
25
-
26
- class NodeDisplayPosition(UniversalBaseModel):
27
- x: float = 0.0
28
- y: float = 0.0
29
-
30
-
31
- class NodeDisplayComment(UniversalBaseModel):
32
- value: Optional[str] = None
33
- expanded: Optional[bool] = None
34
-
35
-
36
- class NodeDisplayData(UniversalBaseModel):
37
- position: NodeDisplayPosition = Field(default_factory=NodeDisplayPosition)
38
- width: Optional[int] = None
39
- height: Optional[int] = None
40
- comment: Optional[NodeDisplayComment] = None
16
+ from vellum_ee.workflows.display.base import WorkflowDisplayData # noqa: F401 - Remove in 0.15.0
17
+ from vellum_ee.workflows.display.base import WorkflowDisplayDataViewport # noqa: F401 - Remove in 0.15.0
18
+ from vellum_ee.workflows.display.editor.types import NodeDisplayComment # noqa: F401 - Remove in 0.15.0
19
+ from vellum_ee.workflows.display.editor.types import NodeDisplayData
20
+ from vellum_ee.workflows.display.editor.types import NodeDisplayPosition # noqa: F401 - Remove in 0.15.0
21
+ from vellum_ee.workflows.display.utils.vellum import NodeInputValuePointerRule
41
22
 
42
23
 
43
24
  class CodeResourceDefinition(UniversalBaseModel):
@@ -45,26 +26,21 @@ class CodeResourceDefinition(UniversalBaseModel):
45
26
  module: List[str]
46
27
 
47
28
 
48
- class WorkflowDisplayDataViewport(UniversalBaseModel):
49
- x: float = 0.0
50
- y: float = 0.0
51
- zoom: float = 1.0
52
-
53
-
54
- class WorkflowDisplayData(UniversalBaseModel):
55
- viewport: WorkflowDisplayDataViewport = Field(default_factory=WorkflowDisplayDataViewport)
56
-
57
-
58
29
  @dataclass
59
- class WorkflowMetaVellumDisplayOverrides(WorkflowMetaDisplay, WorkflowMetaDisplayOverrides):
60
- entrypoint_node_id: UUID
61
- entrypoint_node_source_handle_id: UUID
62
- entrypoint_node_display: NodeDisplayData
63
- display_data: WorkflowDisplayData = field(default_factory=WorkflowDisplayData)
30
+ class WorkflowMetaVellumDisplayOverrides(WorkflowMetaDisplayOverrides):
31
+ """
32
+ DEPRECATED: Use WorkflowMetaDisplay instead. Will be removed in 0.15.0
33
+ """
34
+
35
+ pass
64
36
 
65
37
 
66
38
  @dataclass
67
39
  class WorkflowMetaVellumDisplay(WorkflowMetaVellumDisplayOverrides):
40
+ """
41
+ DEPRECATED: Use WorkflowMetaDisplay instead. Will be removed in 0.15.0
42
+ """
43
+
68
44
  pass
69
45
 
70
46
 
@@ -115,13 +91,21 @@ class EdgeVellumDisplay(EdgeVellumDisplayOverrides):
115
91
 
116
92
 
117
93
  @dataclass
118
- class EntrypointVellumDisplayOverrides(EntrypointDisplay, EntrypointDisplayOverrides):
119
- edge_display: EdgeDisplay
94
+ class EntrypointVellumDisplayOverrides(EntrypointDisplayOverrides):
95
+ """
96
+ DEPRECATED: Use EntrypointDisplay instead. Will be removed in 0.15.0
97
+ """
98
+
99
+ pass
120
100
 
121
101
 
122
102
  @dataclass
123
103
  class EntrypointVellumDisplay(EntrypointVellumDisplayOverrides):
124
- edge_display: EdgeDisplay
104
+ """
105
+ DEPRECATED: Use EntrypointDisplay instead. Will be removed in 0.15.0
106
+ """
107
+
108
+ pass
125
109
 
126
110
 
127
111
  @dataclass
@@ -145,61 +129,6 @@ class WorkflowOutputVellumDisplay(WorkflowOutputVellumDisplayOverrides):
145
129
  pass
146
130
 
147
131
 
148
- class ConstantValuePointer(UniversalBaseModel):
149
- type: Literal["CONSTANT_VALUE"] = "CONSTANT_VALUE"
150
- data: VellumValue
151
-
152
-
153
- ArrayVellumValue.model_rebuild()
154
-
155
-
156
- class NodeOutputData(UniversalBaseModel):
157
- node_id: str
158
- output_id: str
159
-
160
-
161
- class NodeOutputPointer(UniversalBaseModel):
162
- type: Literal["NODE_OUTPUT"] = "NODE_OUTPUT"
163
- data: NodeOutputData
164
-
165
-
166
- class InputVariableData(UniversalBaseModel):
167
- input_variable_id: str
168
-
169
-
170
- class InputVariablePointer(UniversalBaseModel):
171
- type: Literal["INPUT_VARIABLE"] = "INPUT_VARIABLE"
172
- data: InputVariableData
173
-
174
-
175
- class WorkspaceSecretData(UniversalBaseModel):
176
- type: VellumVariableType
177
- workspace_secret_id: Optional[str] = None
178
-
179
-
180
- class WorkspaceSecretPointer(UniversalBaseModel):
181
- type: Literal["WORKSPACE_SECRET"] = "WORKSPACE_SECRET"
182
- data: WorkspaceSecretData
183
-
184
-
185
- class ExecutionCounterData(UniversalBaseModel):
186
- node_id: str
187
-
188
-
189
- class ExecutionCounterPointer(UniversalBaseModel):
190
- type: Literal["EXECUTION_COUNTER"] = "EXECUTION_COUNTER"
191
- data: ExecutionCounterData
192
-
193
-
194
- NodeInputValuePointerRule = Union[
195
- NodeOutputPointer,
196
- InputVariablePointer,
197
- ConstantValuePointer,
198
- WorkspaceSecretPointer,
199
- ExecutionCounterPointer,
200
- ]
201
-
202
-
203
132
  class NodeInputValuePointer(UniversalBaseModel):
204
133
  rules: List[NodeInputValuePointerRule]
205
134
  combinator: Literal["OR"] = "OR"
@@ -19,22 +19,29 @@ from vellum.workflows.types.generics import WorkflowType
19
19
  from vellum.workflows.utils.uuids import uuid4_from_hash
20
20
  from vellum_ee.workflows.display.base import (
21
21
  EdgeDisplay,
22
- EntrypointDisplayOverridesType,
23
- EntrypointDisplayType,
22
+ EntrypointDisplay,
24
23
  StateValueDisplayOverridesType,
25
24
  StateValueDisplayType,
26
25
  WorkflowInputsDisplayOverridesType,
27
26
  WorkflowInputsDisplayType,
28
- WorkflowMetaDisplayOverridesType,
29
- WorkflowMetaDisplayType,
27
+ WorkflowMetaDisplay,
30
28
  WorkflowOutputDisplay,
31
29
  )
30
+ from vellum_ee.workflows.display.editor.types import NodeDisplayData
32
31
  from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
33
32
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
34
33
  from vellum_ee.workflows.display.nodes.get_node_display_class import get_node_display_class
35
- from vellum_ee.workflows.display.nodes.types import NodeOutputDisplay, PortDisplay, PortDisplayOverrides
34
+ from vellum_ee.workflows.display.nodes.types import NodeOutputDisplay, PortDisplay
36
35
  from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
37
- from vellum_ee.workflows.display.types import WorkflowDisplayContext
36
+ from vellum_ee.workflows.display.types import (
37
+ EdgeDisplays,
38
+ EntrypointDisplays,
39
+ NodeDisplays,
40
+ NodeOutputDisplays,
41
+ PortDisplays,
42
+ WorkflowDisplayContext,
43
+ WorkflowOutputDisplays,
44
+ )
38
45
  from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
39
46
 
40
47
  logger = logging.getLogger(__name__)
@@ -43,18 +50,14 @@ logger = logging.getLogger(__name__)
43
50
  class BaseWorkflowDisplay(
44
51
  Generic[
45
52
  WorkflowType,
46
- WorkflowMetaDisplayType,
47
- WorkflowMetaDisplayOverridesType,
48
53
  WorkflowInputsDisplayType,
49
54
  WorkflowInputsDisplayOverridesType,
50
55
  StateValueDisplayType,
51
56
  StateValueDisplayOverridesType,
52
- EntrypointDisplayType,
53
- EntrypointDisplayOverridesType,
54
57
  ]
55
58
  ):
56
59
  # Used to specify the display data for a workflow.
57
- workflow_display: Optional[WorkflowMetaDisplayOverridesType] = None
60
+ workflow_display: Optional[WorkflowMetaDisplay] = None
58
61
 
59
62
  # Used to explicitly specify display data for a workflow's inputs.
60
63
  inputs_display: Dict[WorkflowInputReference, WorkflowInputsDisplayOverridesType] = {}
@@ -63,16 +66,16 @@ class BaseWorkflowDisplay(
63
66
  state_value_displays: Dict[StateValueReference, StateValueDisplayOverridesType] = {}
64
67
 
65
68
  # Used to explicitly specify display data for a workflow's entrypoints.
66
- entrypoint_displays: Dict[Type[BaseNode], EntrypointDisplayOverridesType] = {}
69
+ entrypoint_displays: EntrypointDisplays = {}
67
70
 
68
71
  # Used to explicitly specify display data for a workflow's outputs.
69
- output_displays: Dict[BaseDescriptor, WorkflowOutputDisplay] = {}
72
+ output_displays: WorkflowOutputDisplays = {}
70
73
 
71
74
  # Used to explicitly specify display data for a workflow's edges.
72
- edge_displays: Dict[Tuple[Port, Type[BaseNode]], EdgeDisplay] = {}
75
+ edge_displays: EdgeDisplays = {}
73
76
 
74
77
  # Used to explicitly specify display data for a workflow's ports.
75
- port_displays: Dict[Port, PortDisplayOverrides] = {}
78
+ port_displays: PortDisplays = {}
76
79
 
77
80
  # Used to store the mapping between workflows and their display classes
78
81
  _workflow_display_registry: Dict[Type[WorkflowType], Type["BaseWorkflowDisplay"]] = {}
@@ -87,10 +90,8 @@ class BaseWorkflowDisplay(
87
90
  *,
88
91
  parent_display_context: Optional[
89
92
  WorkflowDisplayContext[
90
- WorkflowMetaDisplayType,
91
93
  WorkflowInputsDisplayType,
92
94
  StateValueDisplayType,
93
- EntrypointDisplayType,
94
95
  ]
95
96
  ] = None,
96
97
  dry_run: bool = False,
@@ -183,50 +184,40 @@ class BaseWorkflowDisplay(
183
184
  def display_context(
184
185
  self,
185
186
  ) -> WorkflowDisplayContext[
186
- WorkflowMetaDisplayType,
187
187
  WorkflowInputsDisplayType,
188
188
  StateValueDisplayType,
189
- EntrypointDisplayType,
190
189
  ]:
191
- workflow_display = self._generate_workflow_meta_display()
190
+ workflow_meta_display = self._generate_workflow_meta_display()
192
191
 
193
- global_node_output_displays: Dict[OutputReference, Tuple[Type[BaseNode], NodeOutputDisplay]] = (
192
+ global_node_output_displays: NodeOutputDisplays = (
194
193
  copy(self._parent_display_context.global_node_output_displays) if self._parent_display_context else {}
195
194
  )
196
195
 
197
- node_displays: Dict[Type[BaseNode], BaseNodeDisplay] = {}
196
+ node_displays: NodeDisplays = {}
198
197
 
199
- global_node_displays: Dict[Type[BaseNode], BaseNodeDisplay] = (
198
+ global_node_displays: NodeDisplays = (
200
199
  copy(self._parent_display_context.global_node_displays) if self._parent_display_context else {}
201
200
  )
202
201
 
203
- port_displays: Dict[Port, PortDisplay] = {}
202
+ port_displays: PortDisplays = {}
204
203
 
205
204
  for node in self._workflow.get_nodes():
206
- extracted_node_displays = self._extract_node_displays(node)
207
-
208
- for extracted_node, extracted_node_display in extracted_node_displays.items():
209
- if extracted_node not in node_displays:
210
- node_displays[extracted_node] = extracted_node_display
211
-
212
- if extracted_node not in global_node_displays:
213
- global_node_displays[extracted_node] = extracted_node_display
214
-
215
- self._enrich_global_node_output_displays(node, extracted_node_displays[node], global_node_output_displays)
216
- self._enrich_node_port_displays(node, extracted_node_displays[node], port_displays)
205
+ self._enrich_node_displays(
206
+ node=node,
207
+ node_displays=node_displays,
208
+ global_node_displays=global_node_displays,
209
+ global_node_output_displays=global_node_output_displays,
210
+ port_displays=port_displays,
211
+ )
217
212
 
218
213
  for node in self._workflow.get_unused_nodes():
219
- extracted_node_displays = self._extract_node_displays(node)
220
-
221
- for extracted_node, extracted_node_display in extracted_node_displays.items():
222
- if extracted_node not in node_displays:
223
- node_displays[extracted_node] = extracted_node_display
224
-
225
- if extracted_node not in global_node_displays:
226
- global_node_displays[extracted_node] = extracted_node_display
227
-
228
- self._enrich_global_node_output_displays(node, extracted_node_displays[node], global_node_output_displays)
229
- self._enrich_node_port_displays(node, extracted_node_displays[node], port_displays)
214
+ self._enrich_node_displays(
215
+ node=node,
216
+ node_displays=node_displays,
217
+ global_node_displays=global_node_displays,
218
+ global_node_output_displays=global_node_output_displays,
219
+ port_displays=port_displays,
220
+ )
230
221
 
231
222
  workflow_input_displays: Dict[WorkflowInputReference, WorkflowInputsDisplayType] = {}
232
223
  # If we're dealing with a nested workflow, then it should have access to the inputs of its parents.
@@ -253,14 +244,14 @@ class BaseWorkflowDisplay(
253
244
  state_value_displays[state_value] = state_value_display
254
245
  global_state_value_displays[state_value] = state_value_display
255
246
 
256
- entrypoint_displays: Dict[Type[BaseNode], EntrypointDisplayType] = {}
247
+ entrypoint_displays: EntrypointDisplays = {}
257
248
  for entrypoint in self._workflow.get_entrypoints():
258
249
  if entrypoint in entrypoint_displays:
259
250
  continue
260
251
 
261
252
  entrypoint_display_overrides = self.entrypoint_displays.get(entrypoint)
262
253
  entrypoint_displays[entrypoint] = self._generate_entrypoint_display(
263
- entrypoint, workflow_display, node_displays, overrides=entrypoint_display_overrides
254
+ entrypoint, workflow_meta_display, node_displays, overrides=entrypoint_display_overrides
264
255
  )
265
256
 
266
257
  edge_displays: Dict[Tuple[Port, Type[BaseNode]], EdgeDisplay] = {}
@@ -296,7 +287,7 @@ class BaseWorkflowDisplay(
296
287
  )
297
288
 
298
289
  return WorkflowDisplayContext(
299
- workflow_display=workflow_display,
290
+ workflow_display=workflow_meta_display,
300
291
  workflow_input_displays=workflow_input_displays,
301
292
  global_workflow_input_displays=global_workflow_input_displays,
302
293
  state_value_displays=state_value_displays,
@@ -311,9 +302,24 @@ class BaseWorkflowDisplay(
311
302
  workflow_display_class=self.__class__,
312
303
  )
313
304
 
314
- @abstractmethod
315
- def _generate_workflow_meta_display(self) -> WorkflowMetaDisplayType:
316
- pass
305
+ def _generate_workflow_meta_display(self) -> WorkflowMetaDisplay:
306
+ overrides = self.workflow_display
307
+ if overrides:
308
+ return WorkflowMetaDisplay(
309
+ entrypoint_node_id=overrides.entrypoint_node_id,
310
+ entrypoint_node_source_handle_id=overrides.entrypoint_node_source_handle_id,
311
+ entrypoint_node_display=overrides.entrypoint_node_display,
312
+ display_data=overrides.display_data,
313
+ )
314
+
315
+ entrypoint_node_id = uuid4_from_hash(f"{self.workflow_id}|entrypoint_node_id")
316
+ entrypoint_node_source_handle_id = uuid4_from_hash(f"{self.workflow_id}|entrypoint_node_source_handle_id")
317
+
318
+ return WorkflowMetaDisplay(
319
+ entrypoint_node_id=entrypoint_node_id,
320
+ entrypoint_node_source_handle_id=entrypoint_node_source_handle_id,
321
+ entrypoint_node_display=NodeDisplayData(),
322
+ )
317
323
 
318
324
  @abstractmethod
319
325
  def _generate_workflow_input_display(
@@ -327,15 +333,31 @@ class BaseWorkflowDisplay(
327
333
  ) -> StateValueDisplayType:
328
334
  pass
329
335
 
330
- @abstractmethod
331
336
  def _generate_entrypoint_display(
332
337
  self,
333
338
  entrypoint: Type[BaseNode],
334
- workflow_display: WorkflowMetaDisplayType,
339
+ workflow_display: WorkflowMetaDisplay,
335
340
  node_displays: Dict[Type[BaseNode], BaseNodeDisplay],
336
- overrides: Optional[EntrypointDisplayOverridesType] = None,
337
- ) -> EntrypointDisplayType:
338
- pass
341
+ overrides: Optional[EntrypointDisplay] = None,
342
+ ) -> EntrypointDisplay:
343
+ entrypoint_node_id = workflow_display.entrypoint_node_id
344
+
345
+ edge_display_overrides = overrides.edge_display if overrides else None
346
+ entrypoint_id = (
347
+ edge_display_overrides.id
348
+ if edge_display_overrides
349
+ else uuid4_from_hash(f"{self.workflow_id}|id|{entrypoint_node_id}")
350
+ )
351
+
352
+ entrypoint_target = get_unadorned_node(entrypoint)
353
+ target_node_display = node_displays[entrypoint_target]
354
+ target_node_id = target_node_display.node_id
355
+
356
+ edge_display = edge_display_overrides or self._generate_edge_display_from_source(
357
+ entrypoint_node_id, target_node_id
358
+ )
359
+
360
+ return EntrypointDisplay(id=entrypoint_id, edge_display=edge_display)
339
361
 
340
362
  def _generate_workflow_output_display(self, output: BaseDescriptor) -> WorkflowOutputDisplay:
341
363
  output_id = uuid4_from_hash(f"{self.workflow_id}|id|{output.name}")
@@ -418,6 +440,26 @@ class BaseWorkflowDisplay(
418
440
  )
419
441
  return display_meta
420
442
 
443
+ def _enrich_node_displays(
444
+ self,
445
+ node: Type[BaseNode],
446
+ node_displays: NodeDisplays,
447
+ global_node_displays: NodeDisplays,
448
+ global_node_output_displays: NodeOutputDisplays,
449
+ port_displays: PortDisplays,
450
+ ) -> None:
451
+ extracted_node_displays = self._extract_node_displays(node)
452
+
453
+ for extracted_node, extracted_node_display in extracted_node_displays.items():
454
+ if extracted_node not in node_displays:
455
+ node_displays[extracted_node] = extracted_node_display
456
+
457
+ if extracted_node not in global_node_displays:
458
+ global_node_displays[extracted_node] = extracted_node_display
459
+
460
+ self._enrich_global_node_output_displays(node, extracted_node_displays[node], global_node_output_displays)
461
+ self._enrich_node_port_displays(node, extracted_node_displays[node], port_displays)
462
+
421
463
  def _extract_node_displays(self, node: Type[BaseNode]) -> Dict[Type[BaseNode], BaseNodeDisplay]:
422
464
  node_display = self._get_node_display(node)
423
465
  additional_node_displays: Dict[Type[BaseNode], BaseNodeDisplay] = {
@@ -7,10 +7,10 @@ from vellum.workflows.nodes.core.retry_node.node import RetryNode
7
7
  from vellum.workflows.nodes.core.templating_node.node import TemplatingNode
8
8
  from vellum.workflows.nodes.core.try_node.node import TryNode
9
9
  from vellum.workflows.workflows.base import BaseWorkflow
10
+ from vellum_ee.workflows.display.editor.types import NodeDisplayData, NodeDisplayPosition
10
11
  from vellum_ee.workflows.display.nodes import BaseNodeDisplay
11
12
  from vellum_ee.workflows.display.nodes.vellum.retry_node import BaseRetryNodeDisplay
12
13
  from vellum_ee.workflows.display.nodes.vellum.try_node import BaseTryNodeDisplay
13
- from vellum_ee.workflows.display.vellum import NodeDisplayData, NodeDisplayPosition
14
14
  from vellum_ee.workflows.display.workflows import VellumWorkflowDisplay
15
15
  from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
16
16
 
@@ -1,9 +1,8 @@
1
1
  import logging
2
2
  from uuid import UUID
3
- from typing import Dict, Optional, Type, cast
3
+ from typing import Optional, cast
4
4
 
5
5
  from vellum.workflows.descriptors.base import BaseDescriptor
6
- from vellum.workflows.nodes.bases import BaseNode
7
6
  from vellum.workflows.nodes.displayable.bases.utils import primitive_to_vellum_value
8
7
  from vellum.workflows.nodes.displayable.final_output_node import FinalOutputNode
9
8
  from vellum.workflows.nodes.utils import get_unadorned_node, get_unadorned_port
@@ -12,20 +11,16 @@ from vellum.workflows.references.output import OutputReference
12
11
  from vellum.workflows.types.core import JsonArray, JsonObject
13
12
  from vellum.workflows.types.generics import WorkflowType
14
13
  from vellum.workflows.utils.uuids import uuid4_from_hash
14
+ from vellum_ee.workflows.display.editor.types import NodeDisplayData
15
15
  from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
16
16
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
17
17
  from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
18
18
  from vellum_ee.workflows.display.utils.vellum import infer_vellum_variable_type
19
19
  from vellum_ee.workflows.display.vellum import (
20
- EntrypointVellumDisplay,
21
- EntrypointVellumDisplayOverrides,
22
- NodeDisplayData,
23
20
  StateValueVellumDisplay,
24
21
  StateValueVellumDisplayOverrides,
25
22
  WorkflowInputsVellumDisplay,
26
23
  WorkflowInputsVellumDisplayOverrides,
27
- WorkflowMetaVellumDisplay,
28
- WorkflowMetaVellumDisplayOverrides,
29
24
  )
30
25
  from vellum_ee.workflows.display.workflows.base_workflow_display import BaseWorkflowDisplay
31
26
 
@@ -35,14 +30,10 @@ logger = logging.getLogger(__name__)
35
30
  class VellumWorkflowDisplay(
36
31
  BaseWorkflowDisplay[
37
32
  WorkflowType,
38
- WorkflowMetaVellumDisplay,
39
- WorkflowMetaVellumDisplayOverrides,
40
33
  WorkflowInputsVellumDisplay,
41
34
  WorkflowInputsVellumDisplayOverrides,
42
35
  StateValueVellumDisplay,
43
36
  StateValueVellumDisplayOverrides,
44
- EntrypointVellumDisplay,
45
- EntrypointVellumDisplayOverrides,
46
37
  ]
47
38
  ):
48
39
  node_display_base_class = BaseNodeDisplay
@@ -290,25 +281,6 @@ class VellumWorkflowDisplay(
290
281
  "output_variables": output_variables,
291
282
  }
292
283
 
293
- def _generate_workflow_meta_display(self) -> WorkflowMetaVellumDisplay:
294
- overrides = self.workflow_display
295
- if overrides:
296
- return WorkflowMetaVellumDisplay(
297
- entrypoint_node_id=overrides.entrypoint_node_id,
298
- entrypoint_node_source_handle_id=overrides.entrypoint_node_source_handle_id,
299
- entrypoint_node_display=overrides.entrypoint_node_display,
300
- display_data=overrides.display_data,
301
- )
302
-
303
- entrypoint_node_id = uuid4_from_hash(f"{self.workflow_id}|entrypoint_node_id")
304
- entrypoint_node_source_handle_id = uuid4_from_hash(f"{self.workflow_id}|entrypoint_node_source_handle_id")
305
-
306
- return WorkflowMetaVellumDisplay(
307
- entrypoint_node_id=entrypoint_node_id,
308
- entrypoint_node_source_handle_id=entrypoint_node_source_handle_id,
309
- entrypoint_node_display=NodeDisplayData(),
310
- )
311
-
312
284
  def _generate_workflow_input_display(
313
285
  self, workflow_input: WorkflowInputReference, overrides: Optional[WorkflowInputsVellumDisplayOverrides] = None
314
286
  ) -> WorkflowInputsVellumDisplay:
@@ -342,29 +314,3 @@ class VellumWorkflowDisplay(
342
314
  state_value_id = uuid4_from_hash(f"{self.workflow_id}|state_values|id|{state_value.name}")
343
315
 
344
316
  return StateValueVellumDisplay(id=state_value_id, name=name, required=required, color=color)
345
-
346
- def _generate_entrypoint_display(
347
- self,
348
- entrypoint: Type[BaseNode],
349
- workflow_display: WorkflowMetaVellumDisplay,
350
- node_displays: Dict[Type[BaseNode], BaseNodeDisplay],
351
- overrides: Optional[EntrypointVellumDisplayOverrides] = None,
352
- ) -> EntrypointVellumDisplay:
353
- entrypoint_node_id = workflow_display.entrypoint_node_id
354
-
355
- edge_display_overrides = overrides.edge_display if overrides else None
356
- entrypoint_id = (
357
- edge_display_overrides.id
358
- if edge_display_overrides
359
- else uuid4_from_hash(f"{self.workflow_id}|id|{entrypoint_node_id}")
360
- )
361
-
362
- entrypoint_target = get_unadorned_node(entrypoint)
363
- target_node_display = node_displays[entrypoint_target]
364
- target_node_id = target_node_display.node_id
365
-
366
- edge_display = edge_display_overrides or self._generate_edge_display_from_source(
367
- entrypoint_node_id, target_node_id
368
- )
369
-
370
- return EntrypointVellumDisplay(id=entrypoint_id, edge_display=edge_display)