vellum-ai 0.14.19__py3-none-any.whl → 0.14.21__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 (44) hide show
  1. vellum/client/core/client_wrapper.py +1 -1
  2. vellum/workflows/nodes/displayable/api_node/node.py +1 -1
  3. vellum/workflows/nodes/displayable/bases/api_node/node.py +7 -2
  4. vellum/workflows/nodes/displayable/code_execution_node/node.py +1 -1
  5. vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +41 -0
  6. vellum/workflows/nodes/displayable/code_execution_node/utils.py +6 -1
  7. vellum/workflows/nodes/tests/test_utils.py +34 -2
  8. vellum/workflows/nodes/utils.py +26 -0
  9. vellum/workflows/references/lazy.py +9 -1
  10. vellum/workflows/references/tests/test_lazy.py +30 -0
  11. {vellum_ai-0.14.19.dist-info → vellum_ai-0.14.21.dist-info}/METADATA +1 -1
  12. {vellum_ai-0.14.19.dist-info → vellum_ai-0.14.21.dist-info}/RECORD +44 -42
  13. vellum_ee/workflows/display/base.py +6 -6
  14. vellum_ee/workflows/display/nodes/base_node_display.py +27 -2
  15. vellum_ee/workflows/display/nodes/base_node_vellum_display.py +0 -20
  16. vellum_ee/workflows/display/nodes/get_node_display_class.py +3 -3
  17. vellum_ee/workflows/display/nodes/vellum/api_node.py +9 -16
  18. vellum_ee/workflows/display/nodes/vellum/code_execution_node.py +7 -3
  19. vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +2 -6
  20. vellum_ee/workflows/display/nodes/vellum/merge_node.py +8 -5
  21. vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +2 -6
  22. vellum_ee/workflows/display/nodes/vellum/tests/test_code_execution_node.py +113 -0
  23. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py +2 -2
  24. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +4 -4
  25. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +8 -8
  26. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py +3 -3
  27. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py +14 -14
  28. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py +3 -3
  29. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +5 -5
  30. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_default_state_serialization.py +1 -1
  31. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_generic_node_serialization.py +1 -1
  32. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +2 -2
  33. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +2 -2
  34. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +3 -3
  35. vellum_ee/workflows/display/types.py +4 -7
  36. vellum_ee/workflows/display/vellum.py +11 -3
  37. vellum_ee/workflows/display/workflows/base_workflow_display.py +45 -34
  38. vellum_ee/workflows/display/workflows/vellum_workflow_display.py +33 -80
  39. vellum_ee/workflows/server/virtual_file_loader.py +52 -22
  40. vellum_ee/workflows/tests/local_workflow/display/workflow.py +3 -5
  41. vellum_ee/workflows/tests/test_server.py +61 -0
  42. {vellum_ai-0.14.19.dist-info → vellum_ai-0.14.21.dist-info}/LICENSE +0 -0
  43. {vellum_ai-0.14.19.dist-info → vellum_ai-0.14.21.dist-info}/WHEEL +0 -0
  44. {vellum_ai-0.14.19.dist-info → vellum_ai-0.14.21.dist-info}/entry_points.txt +0 -0
@@ -638,7 +638,7 @@ def test_serialize_workflow():
638
638
  "source_node_id": "9b619e4d-b0a7-4121-9060-100d457868cb",
639
639
  "source_handle_id": "3a45b81f-95e4-4cbd-8997-bfdbe30251e8",
640
640
  "target_node_id": "0d959311-c836-4641-a867-58f63df9dfea",
641
- "target_handle_id": "139c6965-68f0-4bae-a6d9-3ee68d6347c0",
641
+ "target_handle_id": "7beba198-c452-4749-a38a-ea9420d84e14",
642
642
  "type": "DEFAULT",
643
643
  },
644
644
  {
@@ -646,7 +646,7 @@ def test_serialize_workflow():
646
646
  "source_node_id": "9b619e4d-b0a7-4121-9060-100d457868cb",
647
647
  "source_handle_id": "7202f702-1ebc-4067-ab1e-ec67e49158ee",
648
648
  "target_node_id": "68c02b7c-5077-4087-803d-841474a8081f",
649
- "target_handle_id": "6d2c998b-1525-475f-9327-d8495b5e2692",
649
+ "target_handle_id": "1dc4eebe-b6db-4229-96e5-115ff8cedb76",
650
650
  "type": "DEFAULT",
651
651
  },
652
652
  {
@@ -654,7 +654,7 @@ def test_serialize_workflow():
654
654
  "source_node_id": "9b619e4d-b0a7-4121-9060-100d457868cb",
655
655
  "source_handle_id": "cf45705d-1a47-43a6-9d24-a7fdf78baae0",
656
656
  "target_node_id": "8df781b1-ff28-48a5-98a2-d7d796b932b0",
657
- "target_handle_id": "4584996a-4c1e-45d0-8f49-6918d69b755e",
657
+ "target_handle_id": "b73c39be-cbfe-4225-86e6-e6e4c161881e",
658
658
  "type": "DEFAULT",
659
659
  },
660
660
  {
@@ -662,7 +662,7 @@ def test_serialize_workflow():
662
662
  "source_node_id": "9b619e4d-b0a7-4121-9060-100d457868cb",
663
663
  "source_handle_id": "f04610dd-61cf-41b0-b337-2235e101cdb0",
664
664
  "target_node_id": "ed7caf01-9ae7-47a3-b15a-16697abaf486",
665
- "target_handle_id": "8da86a9b-0d22-442c-b622-63afe1b569ab",
665
+ "target_handle_id": "76fe7aec-5cd4-4c1a-b386-cfe09ebe66e4",
666
666
  "type": "DEFAULT",
667
667
  },
668
668
  {
@@ -670,7 +670,7 @@ def test_serialize_workflow():
670
670
  "source_node_id": "9b619e4d-b0a7-4121-9060-100d457868cb",
671
671
  "source_handle_id": "f9dde637-ea90-465f-a871-caf8380ae377",
672
672
  "target_node_id": "148c61bd-e8b0-4d4b-8734-b043a72b90ed",
673
- "target_handle_id": "f81bbac8-d7f1-4bfd-95ec-9d0b93e28114",
673
+ "target_handle_id": "c88839af-3a79-4310-abbd-e1553d981dce",
674
674
  "type": "DEFAULT",
675
675
  },
676
676
  {
@@ -196,7 +196,7 @@ def test_serialize_workflow():
196
196
  "source_node_id": "32684932-7c7c-4b1c-aed2-553de29bf3f7",
197
197
  "source_handle_id": "e4136ee4-a51a-4ca3-9a3a-aa96f5de2347",
198
198
  "target_node_id": "1381c078-efa2-4255-89a1-7b4cb742c7fc",
199
- "target_handle_id": "a95a34f2-e894-4fb6-a2c9-15d12c1e3135",
199
+ "target_handle_id": "6492efcf-4437-4af1-9ad7-269795ccb27a",
200
200
  "type": "DEFAULT",
201
201
  },
202
202
  {
@@ -124,7 +124,7 @@ def test_serialize_workflow(vellum_client):
124
124
  "source_node_id": "f1e4678f-c470-400b-a40e-c8922cc99a86",
125
125
  "source_handle_id": "40201804-8beb-43ad-8873-a027759512f1",
126
126
  "target_node_id": "c2ed23f7-f6cb-4a56-a91c-2e5f9d8fda7f",
127
- "target_handle_id": "9d3a1b3d-4a38-4f2e-bbf1-dd8be152bce8",
127
+ "target_handle_id": "b7bfb298-959a-4d2b-8b85-bbd0d2522703",
128
128
  "type": "DEFAULT",
129
129
  },
130
130
  {
@@ -142,7 +142,7 @@ def test_serialize_workflow():
142
142
  "module": ["tests", "workflows", "basic_inline_subworkflow", "workflow"],
143
143
  },
144
144
  "trigger": {
145
- "id": "a95a34f2-e894-4fb6-a2c9-15d12c1e3135",
145
+ "id": "6492efcf-4437-4af1-9ad7-269795ccb27a",
146
146
  "merge_behavior": "AWAIT_ATTRIBUTES",
147
147
  },
148
148
  "ports": [
@@ -261,7 +261,7 @@ def test_serialize_workflow():
261
261
  "source_node_id": "afa49a0f-db35-4552-9217-5b8f237e84bc",
262
262
  "source_handle_id": "9914a6a0-9a99-430d-8ddd-f7c13847fe1a",
263
263
  "target_node_id": "1381c078-efa2-4255-89a1-7b4cb742c7fc",
264
- "target_handle_id": "a95a34f2-e894-4fb6-a2c9-15d12c1e3135",
264
+ "target_handle_id": "6492efcf-4437-4af1-9ad7-269795ccb27a",
265
265
  "type": "DEFAULT",
266
266
  },
267
267
  {
@@ -131,7 +131,7 @@ def test_serialize_workflow():
131
131
  "module": ["tests", "workflows", "basic_map_node", "workflow"],
132
132
  },
133
133
  "trigger": {
134
- "id": "01324747-9bc0-4ecd-a8ab-40dca5a94e2e",
134
+ "id": "551d5528-f4e1-42ea-bde0-9de4b4968253",
135
135
  "merge_behavior": "AWAIT_ATTRIBUTES",
136
136
  },
137
137
  "ports": [
@@ -215,7 +215,7 @@ def test_serialize_workflow():
215
215
  "source_node_id": "ff9bfe6e-839d-4d40-b8fc-313b3bbd0ab0",
216
216
  "source_handle_id": "520d3616-8369-4e79-9da5-3febae299c2a",
217
217
  "target_node_id": "baf6d316-dc75-41e8-96c0-015aede96309",
218
- "target_handle_id": "01324747-9bc0-4ecd-a8ab-40dca5a94e2e",
218
+ "target_handle_id": "551d5528-f4e1-42ea-bde0-9de4b4968253",
219
219
  "type": "DEFAULT",
220
220
  },
221
221
  {
@@ -146,7 +146,7 @@ def test_serialize_workflow__await_all():
146
146
  "source_node_id": "dc8aecd0-49ba-4464-a45f-29d3bfd686e4",
147
147
  "source_handle_id": "017d40f5-8326-4e42-a409-b08995defaa8",
148
148
  "target_node_id": "59243c65-053f-4ea6-9157-3f3edb1477bf",
149
- "target_handle_id": "75293c10-d6d8-4fc0-afae-ba6437af982e",
149
+ "target_handle_id": "e622fe61-3bca-4aff-86e1-25dad7bdf9d4",
150
150
  "type": "DEFAULT",
151
151
  },
152
152
  {
@@ -154,7 +154,7 @@ def test_serialize_workflow__await_all():
154
154
  "source_node_id": "dc8aecd0-49ba-4464-a45f-29d3bfd686e4",
155
155
  "source_handle_id": "017d40f5-8326-4e42-a409-b08995defaa8",
156
156
  "target_node_id": "127ef456-91bc-43c6-bd8b-1772db5e3cb5",
157
- "target_handle_id": "10c7392f-7dc0-4273-8380-ddc3497e6072",
157
+ "target_handle_id": "e5cc41cb-71db-43ec-b3f0-c78706af3351",
158
158
  "type": "DEFAULT",
159
159
  },
160
160
  {
@@ -178,7 +178,7 @@ def test_serialize_workflow__await_all():
178
178
  "source_node_id": "37c10e8a-771b-432b-a767-31f5007851f0",
179
179
  "source_handle_id": "3bbc469f-0fb0-4b3d-a28b-746fefec2818",
180
180
  "target_node_id": "634f0202-9ea9-4c62-b152-1a58c595cffb",
181
- "target_handle_id": "c0c993cd-1370-480b-b175-59590735aa46",
181
+ "target_handle_id": "acd48f48-54fb-4b2b-ab37-96d336f6dfb3",
182
182
  "type": "DEFAULT",
183
183
  },
184
184
  {
@@ -7,7 +7,7 @@ from vellum.workflows.nodes import BaseNode
7
7
  from vellum.workflows.ports import Port
8
8
  from vellum.workflows.references import OutputReference, StateValueReference, WorkflowInputReference
9
9
  from vellum_ee.workflows.display.base import (
10
- EdgeDisplayType,
10
+ EdgeDisplay,
11
11
  EntrypointDisplayType,
12
12
  StateValueDisplayType,
13
13
  WorkflowInputsDisplayType,
@@ -20,7 +20,6 @@ if TYPE_CHECKING:
20
20
  from vellum_ee.workflows.display.nodes.types import NodeOutputDisplay, PortDisplay
21
21
  from vellum_ee.workflows.display.workflows import BaseWorkflowDisplay
22
22
 
23
- NodeDisplayType = TypeVar("NodeDisplayType", bound="BaseNodeDisplay")
24
23
  WorkflowDisplayType = TypeVar("WorkflowDisplayType", bound="BaseWorkflowDisplay")
25
24
 
26
25
 
@@ -30,9 +29,7 @@ class WorkflowDisplayContext(
30
29
  WorkflowMetaDisplayType,
31
30
  WorkflowInputsDisplayType,
32
31
  StateValueDisplayType,
33
- NodeDisplayType,
34
32
  EntrypointDisplayType,
35
- EdgeDisplayType,
36
33
  ]
37
34
  ):
38
35
  workflow_display_class: Type["BaseWorkflowDisplay"]
@@ -43,12 +40,12 @@ class WorkflowDisplayContext(
43
40
  )
44
41
  state_value_displays: Dict[StateValueReference, StateValueDisplayType] = field(default_factory=dict)
45
42
  global_state_value_displays: Dict[StateValueReference, StateValueDisplayType] = field(default_factory=dict)
46
- node_displays: Dict[Type[BaseNode], "NodeDisplayType"] = field(default_factory=dict)
47
- global_node_displays: Dict[Type[BaseNode], NodeDisplayType] = field(default_factory=dict)
43
+ node_displays: Dict[Type[BaseNode], "BaseNodeDisplay"] = field(default_factory=dict)
44
+ global_node_displays: Dict[Type[BaseNode], "BaseNodeDisplay"] = field(default_factory=dict)
48
45
  global_node_output_displays: Dict[OutputReference, Tuple[Type[BaseNode], "NodeOutputDisplay"]] = field(
49
46
  default_factory=dict
50
47
  )
51
48
  entrypoint_displays: Dict[Type[BaseNode], EntrypointDisplayType] = field(default_factory=dict)
52
49
  workflow_output_displays: Dict[BaseDescriptor, WorkflowOutputDisplay] = field(default_factory=dict)
53
- edge_displays: Dict[Tuple[Port, Type[BaseNode]], EdgeDisplayType] = field(default_factory=dict)
50
+ edge_displays: Dict[Tuple[Port, Type[BaseNode]], EdgeDisplay] = field(default_factory=dict)
54
51
  port_displays: Dict[Port, "PortDisplay"] = field(default_factory=dict)
@@ -93,12 +93,20 @@ class StateValueVellumDisplay(StateValueVellumDisplayOverrides):
93
93
 
94
94
 
95
95
  @dataclass
96
- class EdgeVellumDisplayOverrides(EdgeDisplay, EdgeDisplayOverrides):
96
+ class EdgeVellumDisplayOverrides(EdgeDisplayOverrides):
97
+ """
98
+ DEPRECATED: Use EdgeDisplay instead. Will be removed in 0.15.0
99
+ """
100
+
97
101
  pass
98
102
 
99
103
 
100
104
  @dataclass
101
105
  class EdgeVellumDisplay(EdgeVellumDisplayOverrides):
106
+ """
107
+ DEPRECATED: Use EdgeDisplay instead. Will be removed in 0.15.0
108
+ """
109
+
102
110
  source_node_id: UUID
103
111
  source_handle_id: UUID
104
112
  target_node_id: UUID
@@ -108,12 +116,12 @@ class EdgeVellumDisplay(EdgeVellumDisplayOverrides):
108
116
 
109
117
  @dataclass
110
118
  class EntrypointVellumDisplayOverrides(EntrypointDisplay, EntrypointDisplayOverrides):
111
- edge_display: EdgeVellumDisplayOverrides
119
+ edge_display: EdgeDisplay
112
120
 
113
121
 
114
122
  @dataclass
115
123
  class EntrypointVellumDisplay(EntrypointVellumDisplayOverrides):
116
- edge_display: EdgeVellumDisplay
124
+ edge_display: EdgeDisplay
117
125
 
118
126
 
119
127
  @dataclass
@@ -12,15 +12,14 @@ from vellum.workflows.edges import Edge
12
12
  from vellum.workflows.events.workflow import NodeEventDisplayContext, WorkflowEventDisplayContext
13
13
  from vellum.workflows.expressions.coalesce_expression import CoalesceExpression
14
14
  from vellum.workflows.nodes.bases import BaseNode
15
- from vellum.workflows.nodes.utils import get_wrapped_node
15
+ from vellum.workflows.nodes.utils import get_unadorned_node, get_wrapped_node
16
16
  from vellum.workflows.ports import Port
17
17
  from vellum.workflows.references import OutputReference, StateValueReference, WorkflowInputReference
18
18
  from vellum.workflows.types.core import JsonObject
19
19
  from vellum.workflows.types.generics import WorkflowType
20
20
  from vellum.workflows.utils.uuids import uuid4_from_hash
21
21
  from vellum_ee.workflows.display.base import (
22
- EdgeDisplayOverridesType,
23
- EdgeDisplayType,
22
+ EdgeDisplay,
24
23
  EntrypointDisplayOverridesType,
25
24
  EntrypointDisplayType,
26
25
  StateValueDisplayOverridesType,
@@ -31,11 +30,12 @@ from vellum_ee.workflows.display.base import (
31
30
  WorkflowMetaDisplayType,
32
31
  WorkflowOutputDisplay,
33
32
  )
33
+ from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
34
34
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
35
35
  from vellum_ee.workflows.display.nodes.get_node_display_class import get_node_display_class
36
36
  from vellum_ee.workflows.display.nodes.types import NodeOutputDisplay, PortDisplay, PortDisplayOverrides
37
37
  from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
38
- from vellum_ee.workflows.display.types import NodeDisplayType, WorkflowDisplayContext
38
+ from vellum_ee.workflows.display.types import WorkflowDisplayContext
39
39
  from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
40
40
 
41
41
  logger = logging.getLogger(__name__)
@@ -50,11 +50,8 @@ class BaseWorkflowDisplay(
50
50
  WorkflowInputsDisplayOverridesType,
51
51
  StateValueDisplayType,
52
52
  StateValueDisplayOverridesType,
53
- NodeDisplayType,
54
53
  EntrypointDisplayType,
55
54
  EntrypointDisplayOverridesType,
56
- EdgeDisplayType,
57
- EdgeDisplayOverridesType,
58
55
  ]
59
56
  ):
60
57
  # Used to specify the display data for a workflow.
@@ -73,7 +70,7 @@ class BaseWorkflowDisplay(
73
70
  output_displays: Dict[BaseDescriptor, WorkflowOutputDisplay] = {}
74
71
 
75
72
  # Used to explicitly specify display data for a workflow's edges.
76
- edge_displays: Dict[Tuple[Port, Type[BaseNode]], EdgeDisplayOverridesType] = {}
73
+ edge_displays: Dict[Tuple[Port, Type[BaseNode]], EdgeDisplay] = {}
77
74
 
78
75
  # Used to explicitly specify display data for a workflow's ports.
79
76
  port_displays: Dict[Port, PortDisplayOverrides] = {}
@@ -94,9 +91,7 @@ class BaseWorkflowDisplay(
94
91
  WorkflowMetaDisplayType,
95
92
  WorkflowInputsDisplayType,
96
93
  StateValueDisplayType,
97
- NodeDisplayType,
98
94
  EntrypointDisplayType,
99
- EdgeDisplayType,
100
95
  ]
101
96
  ] = None,
102
97
  dry_run: bool = False,
@@ -124,7 +119,7 @@ class BaseWorkflowDisplay(
124
119
 
125
120
  @property
126
121
  @abstractmethod
127
- def node_display_base_class(self) -> Type[NodeDisplayType]:
122
+ def node_display_base_class(self) -> Type[BaseNodeDisplay]:
128
123
  pass
129
124
 
130
125
  def add_error(self, error: Exception) -> None:
@@ -141,7 +136,7 @@ class BaseWorkflowDisplay(
141
136
  def _enrich_global_node_output_displays(
142
137
  self,
143
138
  node: Type[BaseNode],
144
- node_display: NodeDisplayType,
139
+ node_display: BaseNodeDisplay,
145
140
  node_output_displays: Dict[OutputReference, Tuple[Type[BaseNode], NodeOutputDisplay]],
146
141
  ):
147
142
  """This method recursively adds nodes wrapped in decorators to the node_output_displays dictionary."""
@@ -162,7 +157,7 @@ class BaseWorkflowDisplay(
162
157
  def _enrich_node_port_displays(
163
158
  self,
164
159
  node: Type[BaseNode],
165
- node_display: NodeDisplayType,
160
+ node_display: BaseNodeDisplay,
166
161
  port_displays: Dict[Port, PortDisplay],
167
162
  ):
168
163
  """This method recursively adds nodes wrapped in decorators to the port_displays dictionary."""
@@ -178,7 +173,7 @@ class BaseWorkflowDisplay(
178
173
 
179
174
  port_displays[port] = node_display.get_node_port_display(port)
180
175
 
181
- def _get_node_display(self, node: Type[BaseNode]) -> NodeDisplayType:
176
+ def _get_node_display(self, node: Type[BaseNode]) -> BaseNodeDisplay:
182
177
  node_display_class = get_node_display_class(self.node_display_base_class, node)
183
178
  node_display = node_display_class()
184
179
 
@@ -194,9 +189,7 @@ class BaseWorkflowDisplay(
194
189
  WorkflowMetaDisplayType,
195
190
  WorkflowInputsDisplayType,
196
191
  StateValueDisplayType,
197
- NodeDisplayType,
198
192
  EntrypointDisplayType,
199
- EdgeDisplayType,
200
193
  ]:
201
194
  workflow_display = self._generate_workflow_meta_display()
202
195
 
@@ -204,9 +197,9 @@ class BaseWorkflowDisplay(
204
197
  copy(self._parent_display_context.global_node_output_displays) if self._parent_display_context else {}
205
198
  )
206
199
 
207
- node_displays: Dict[Type[BaseNode], NodeDisplayType] = {}
200
+ node_displays: Dict[Type[BaseNode], BaseNodeDisplay] = {}
208
201
 
209
- global_node_displays: Dict[Type[BaseNode], NodeDisplayType] = (
202
+ global_node_displays: Dict[Type[BaseNode], BaseNodeDisplay] = (
210
203
  copy(self._parent_display_context.global_node_displays) if self._parent_display_context else {}
211
204
  )
212
205
 
@@ -273,14 +266,14 @@ class BaseWorkflowDisplay(
273
266
  entrypoint, workflow_display, node_displays, overrides=entrypoint_display_overrides
274
267
  )
275
268
 
276
- edge_displays: Dict[Tuple[Port, Type[BaseNode]], EdgeDisplayType] = {}
269
+ edge_displays: Dict[Tuple[Port, Type[BaseNode]], EdgeDisplay] = {}
277
270
  for edge in self._workflow.get_edges():
278
271
  if edge in edge_displays:
279
272
  continue
280
273
 
281
274
  edge_display_overrides = self.edge_displays.get((edge.from_port, edge.to_node))
282
275
  edge_displays[(edge.from_port, edge.to_node)] = self._generate_edge_display(
283
- edge, node_displays, port_displays, overrides=edge_display_overrides
276
+ edge, node_displays, overrides=edge_display_overrides
284
277
  )
285
278
 
286
279
  for edge in self._workflow.get_unused_edges():
@@ -289,7 +282,7 @@ class BaseWorkflowDisplay(
289
282
 
290
283
  edge_display_overrides = self.edge_displays.get((edge.from_port, edge.to_node))
291
284
  edge_displays[(edge.from_port, edge.to_node)] = self._generate_edge_display(
292
- edge, node_displays, port_displays, overrides=edge_display_overrides
285
+ edge, node_displays, overrides=edge_display_overrides
293
286
  )
294
287
 
295
288
  workflow_output_displays: Dict[BaseDescriptor, WorkflowOutputDisplay] = {}
@@ -347,7 +340,7 @@ class BaseWorkflowDisplay(
347
340
  self,
348
341
  entrypoint: Type[BaseNode],
349
342
  workflow_display: WorkflowMetaDisplayType,
350
- node_displays: Dict[Type[BaseNode], NodeDisplayType],
343
+ node_displays: Dict[Type[BaseNode], BaseNodeDisplay],
351
344
  overrides: Optional[EntrypointDisplayOverridesType] = None,
352
345
  ) -> EntrypointDisplayType:
353
346
  pass
@@ -357,16 +350,6 @@ class BaseWorkflowDisplay(
357
350
 
358
351
  return WorkflowOutputDisplay(id=output_id, name=output.name)
359
352
 
360
- @abstractmethod
361
- def _generate_edge_display(
362
- self,
363
- edge: Edge,
364
- node_displays: Dict[Type[BaseNode], NodeDisplayType],
365
- port_displays: Dict[Port, PortDisplay],
366
- overrides: Optional[EdgeDisplayOverridesType] = None,
367
- ) -> EdgeDisplayType:
368
- pass
369
-
370
353
  def __init_subclass__(cls, **kwargs: Any) -> None:
371
354
  super().__init_subclass__(**kwargs)
372
355
 
@@ -443,9 +426,9 @@ class BaseWorkflowDisplay(
443
426
  )
444
427
  return display_meta
445
428
 
446
- def _extract_node_displays(self, node: Type[BaseNode]) -> Dict[Type[BaseNode], NodeDisplayType]:
429
+ def _extract_node_displays(self, node: Type[BaseNode]) -> Dict[Type[BaseNode], BaseNodeDisplay]:
447
430
  node_display = self._get_node_display(node)
448
- additional_node_displays: Dict[Type[BaseNode], NodeDisplayType] = {
431
+ additional_node_displays: Dict[Type[BaseNode], BaseNodeDisplay] = {
449
432
  node: node_display,
450
433
  }
451
434
 
@@ -459,3 +442,31 @@ class BaseWorkflowDisplay(
459
442
  additional_node_displays[node] = display
460
443
 
461
444
  return additional_node_displays
445
+
446
+ def _generate_edge_display(
447
+ self,
448
+ edge: Edge,
449
+ node_displays: Dict[Type[BaseNode], BaseNodeDisplay],
450
+ overrides: Optional[EdgeDisplay] = None,
451
+ ) -> EdgeDisplay:
452
+ source_node = get_unadorned_node(edge.from_port.node_class)
453
+ target_node = get_unadorned_node(edge.to_node)
454
+
455
+ source_node_id = node_displays[source_node].node_id
456
+ target_node_id = node_displays[target_node].node_id
457
+
458
+ return self._generate_edge_display_from_source(source_node_id, target_node_id, overrides)
459
+
460
+ def _generate_edge_display_from_source(
461
+ self,
462
+ source_node_id: UUID,
463
+ target_node_id: UUID,
464
+ overrides: Optional[EdgeDisplay] = None,
465
+ ) -> EdgeDisplay:
466
+ edge_id: UUID
467
+ if overrides:
468
+ edge_id = overrides.id
469
+ else:
470
+ edge_id = uuid4_from_hash(f"{self.workflow_id}|id|{source_node_id}|{target_node_id}")
471
+
472
+ return EdgeDisplay(id=edge_id)
@@ -1,14 +1,12 @@
1
1
  import logging
2
2
  from uuid import UUID
3
- from typing import Dict, List, Optional, Type, cast
3
+ from typing import Dict, Optional, Type, cast
4
4
 
5
5
  from vellum.workflows.descriptors.base import BaseDescriptor
6
- from vellum.workflows.edges import Edge
7
6
  from vellum.workflows.nodes.bases import BaseNode
8
7
  from vellum.workflows.nodes.displayable.bases.utils import primitive_to_vellum_value
9
8
  from vellum.workflows.nodes.displayable.final_output_node import FinalOutputNode
10
9
  from vellum.workflows.nodes.utils import get_unadorned_node, get_unadorned_port
11
- from vellum.workflows.ports import Port
12
10
  from vellum.workflows.references import WorkflowInputReference
13
11
  from vellum.workflows.references.output import OutputReference
14
12
  from vellum.workflows.types.core import JsonArray, JsonObject
@@ -16,12 +14,9 @@ from vellum.workflows.types.generics import WorkflowType
16
14
  from vellum.workflows.utils.uuids import uuid4_from_hash
17
15
  from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
18
16
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
19
- from vellum_ee.workflows.display.nodes.types import PortDisplay
20
17
  from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
21
18
  from vellum_ee.workflows.display.utils.vellum import infer_vellum_variable_type
22
19
  from vellum_ee.workflows.display.vellum import (
23
- EdgeVellumDisplay,
24
- EdgeVellumDisplayOverrides,
25
20
  EntrypointVellumDisplay,
26
21
  EntrypointVellumDisplayOverrides,
27
22
  NodeDisplayData,
@@ -46,11 +41,8 @@ class VellumWorkflowDisplay(
46
41
  WorkflowInputsVellumDisplayOverrides,
47
42
  StateValueVellumDisplay,
48
43
  StateValueVellumDisplayOverrides,
49
- BaseNodeDisplay,
50
44
  EntrypointVellumDisplay,
51
45
  EntrypointVellumDisplayOverrides,
52
- EdgeVellumDisplay,
53
- EdgeVellumDisplayOverrides,
54
46
  ]
55
47
  ):
56
48
  node_display_base_class = BaseNodeDisplay
@@ -99,14 +91,16 @@ class VellumWorkflowDisplay(
99
91
  edges: JsonArray = []
100
92
 
101
93
  # Add a single synthetic node for the workflow entrypoint
94
+ entrypoint_node_id = self.display_context.workflow_display.entrypoint_node_id
95
+ entrypoint_node_source_handle_id = self.display_context.workflow_display.entrypoint_node_source_handle_id
102
96
  nodes.append(
103
97
  {
104
- "id": str(self.display_context.workflow_display.entrypoint_node_id),
98
+ "id": str(entrypoint_node_id),
105
99
  "type": "ENTRYPOINT",
106
100
  "inputs": [],
107
101
  "data": {
108
102
  "label": "Entrypoint Node",
109
- "source_handle_id": str(self.display_context.workflow_display.entrypoint_node_source_handle_id),
103
+ "source_handle_id": str(entrypoint_node_source_handle_id),
110
104
  },
111
105
  "display_data": self.display_context.workflow_display.entrypoint_node_display.dict(),
112
106
  "base": None,
@@ -245,25 +239,37 @@ class VellumWorkflowDisplay(
245
239
  )
246
240
 
247
241
  # Add an edge for each edge in the workflow
248
- all_edge_displays: List[EdgeVellumDisplay] = [
249
- # Create a synthetic edge from the synthetic entrypoint node to each actual entrypoint
250
- *[
251
- entrypoint_display.edge_display
252
- for entrypoint_display in self.display_context.entrypoint_displays.values()
253
- ],
254
- # Include the concrete edges in the workflow
255
- *self.display_context.edge_displays.values(),
256
- ]
242
+ for target_node, entrypoint_display in self.display_context.entrypoint_displays.items():
243
+ unadorned_target_node = get_unadorned_node(target_node)
244
+ target_node_display = self.display_context.node_displays[unadorned_target_node]
245
+ edges.append(
246
+ {
247
+ "id": str(entrypoint_display.edge_display.id),
248
+ "source_node_id": str(entrypoint_node_id),
249
+ "source_handle_id": str(entrypoint_node_source_handle_id),
250
+ "target_node_id": str(target_node_display.node_id),
251
+ "target_handle_id": str(target_node_display.get_trigger_id()),
252
+ "type": "DEFAULT",
253
+ }
254
+ )
255
+
256
+ for (source_node_port, target_node), edge_display in self.display_context.edge_displays.items():
257
+ unadorned_source_node_port = get_unadorned_port(source_node_port)
258
+ unadorned_target_node = get_unadorned_node(target_node)
259
+
260
+ source_node_port_display = self.display_context.port_displays[unadorned_source_node_port]
261
+ target_node_display = self.display_context.node_displays[unadorned_target_node]
257
262
 
258
- for edge_display in all_edge_displays:
259
263
  edges.append(
260
264
  {
261
265
  "id": str(edge_display.id),
262
- "source_node_id": str(edge_display.source_node_id),
263
- "source_handle_id": str(edge_display.source_handle_id),
264
- "target_node_id": str(edge_display.target_node_id),
265
- "target_handle_id": str(edge_display.target_handle_id),
266
- "type": edge_display.type,
266
+ "source_node_id": str(source_node_port_display.node_id),
267
+ "source_handle_id": str(source_node_port_display.id),
268
+ "target_node_id": str(target_node_display.node_id),
269
+ "target_handle_id": str(
270
+ target_node_display.get_target_handle_id_by_source_node_id(source_node_port_display.node_id)
271
+ ),
272
+ "type": "DEFAULT",
267
273
  }
268
274
  )
269
275
 
@@ -345,7 +351,6 @@ class VellumWorkflowDisplay(
345
351
  overrides: Optional[EntrypointVellumDisplayOverrides] = None,
346
352
  ) -> EntrypointVellumDisplay:
347
353
  entrypoint_node_id = workflow_display.entrypoint_node_id
348
- source_handle_id = workflow_display.entrypoint_node_source_handle_id
349
354
 
350
355
  edge_display_overrides = overrides.edge_display if overrides else None
351
356
  entrypoint_id = (
@@ -357,61 +362,9 @@ class VellumWorkflowDisplay(
357
362
  entrypoint_target = get_unadorned_node(entrypoint)
358
363
  target_node_display = node_displays[entrypoint_target]
359
364
  target_node_id = target_node_display.node_id
360
- if isinstance(target_node_display, BaseNodeVellumDisplay):
361
- target_handle_id = target_node_display.get_target_handle_id_by_source_node_id(entrypoint_node_id)
362
- else:
363
- target_handle_id = target_node_display.get_trigger_id()
364
365
 
365
366
  edge_display = self._generate_edge_display_from_source(
366
- entrypoint_node_id, source_handle_id, target_node_id, target_handle_id, overrides=edge_display_overrides
367
+ entrypoint_node_id, target_node_id, overrides=edge_display_overrides
367
368
  )
368
369
 
369
370
  return EntrypointVellumDisplay(id=entrypoint_id, edge_display=edge_display)
370
-
371
- def _generate_edge_display(
372
- self,
373
- edge: Edge,
374
- node_displays: Dict[Type[BaseNode], BaseNodeDisplay],
375
- port_displays: Dict[Port, PortDisplay],
376
- overrides: Optional[EdgeVellumDisplayOverrides] = None,
377
- ) -> EdgeVellumDisplay:
378
- source_node = get_unadorned_node(edge.from_port.node_class)
379
- target_node = get_unadorned_node(edge.to_node)
380
-
381
- source_node_id = node_displays[source_node].node_id
382
- from_port = get_unadorned_port(edge.from_port)
383
- source_handle_id = port_displays[from_port].id
384
-
385
- target_node_display = node_displays[target_node]
386
- target_node_id = target_node_display.node_id
387
-
388
- if isinstance(target_node_display, BaseNodeVellumDisplay):
389
- target_handle_id = target_node_display.get_target_handle_id_by_source_node_id(source_node_id)
390
- else:
391
- target_handle_id = target_node_display.get_trigger_id()
392
-
393
- return self._generate_edge_display_from_source(
394
- source_node_id, source_handle_id, target_node_id, target_handle_id, overrides
395
- )
396
-
397
- def _generate_edge_display_from_source(
398
- self,
399
- source_node_id: UUID,
400
- source_handle_id: UUID,
401
- target_node_id: UUID,
402
- target_handle_id: UUID,
403
- overrides: Optional[EdgeVellumDisplayOverrides] = None,
404
- ) -> EdgeVellumDisplay:
405
- edge_id: UUID
406
- if overrides:
407
- edge_id = overrides.id
408
- else:
409
- edge_id = uuid4_from_hash(f"{self.workflow_id}|id|{source_node_id}|{target_node_id}")
410
-
411
- return EdgeVellumDisplay(
412
- id=edge_id,
413
- source_node_id=source_node_id,
414
- target_node_id=target_node_id,
415
- source_handle_id=source_handle_id,
416
- target_handle_id=target_handle_id,
417
- )