vellum-ai 0.12.1__py3-none-any.whl → 0.12.2__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.
@@ -17,7 +17,7 @@ class BaseClientWrapper:
17
17
  headers: typing.Dict[str, str] = {
18
18
  "X-Fern-Language": "Python",
19
19
  "X-Fern-SDK-Name": "vellum-ai",
20
- "X-Fern-SDK-Version": "0.12.1",
20
+ "X-Fern-SDK-Version": "0.12.2",
21
21
  }
22
22
  headers["X_API_KEY"] = self.api_key
23
23
  return headers
@@ -10,7 +10,7 @@ from vellum.workflows.ports.port import Port
10
10
  from vellum.workflows.references.node import NodeReference
11
11
  from vellum.workflows.types.generics import OutputsType
12
12
 
13
- from .types import BaseEvent, default_serializer, serialize_type_encoder
13
+ from .types import BaseEvent, default_serializer, serialize_type_encoder_with_id
14
14
 
15
15
  if TYPE_CHECKING:
16
16
  from vellum.workflows.nodes.bases import BaseNode
@@ -21,7 +21,7 @@ class _BaseNodeExecutionBody(UniversalBaseModel):
21
21
 
22
22
  @field_serializer("node_definition")
23
23
  def serialize_node_definition(self, node_definition: Type, _info: Any) -> Dict[str, Any]:
24
- return serialize_type_encoder(node_definition)
24
+ return serialize_type_encoder_with_id(node_definition)
25
25
 
26
26
  # Couldn't get this to work with model_config.exclude_none or model_config.exclude_defaults
27
27
  # so we're excluding null invoked_ports manually here for now
@@ -28,6 +28,7 @@ from vellum.workflows.inputs.base import BaseInputs
28
28
  from vellum.workflows.nodes.bases.base import BaseNode
29
29
  from vellum.workflows.outputs.base import BaseOutput
30
30
  from vellum.workflows.state.base import BaseState
31
+ from vellum.workflows.utils.uuids import uuid4_from_hash
31
32
  from vellum.workflows.workflows.base import BaseWorkflow
32
33
 
33
34
 
@@ -48,6 +49,8 @@ class MockWorkflow(BaseWorkflow[MockInputs, BaseState]):
48
49
 
49
50
  name_parts = __name__.split(".")
50
51
  module_root = name_parts[: name_parts.index("events")]
52
+ mock_workflow_uuid = str(uuid4_from_hash(MockWorkflow.__qualname__))
53
+ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__))
51
54
 
52
55
 
53
56
  @pytest.mark.parametrize(
@@ -73,6 +76,7 @@ module_root = name_parts[: name_parts.index("events")]
73
76
  "name": "workflow.execution.initiated",
74
77
  "body": {
75
78
  "workflow_definition": {
79
+ "id": mock_workflow_uuid,
76
80
  "name": "MockWorkflow",
77
81
  "module": module_root + ["events", "tests", "test_event"],
78
82
  },
@@ -113,6 +117,7 @@ module_root = name_parts[: name_parts.index("events")]
113
117
  "name": "node.execution.initiated",
114
118
  "body": {
115
119
  "node_definition": {
120
+ "id": mock_node_uuid,
116
121
  "name": "MockNode",
117
122
  "module": module_root + ["events", "tests", "test_event"],
118
123
  },
@@ -122,11 +127,13 @@ module_root = name_parts[: name_parts.index("events")]
122
127
  },
123
128
  "parent": {
124
129
  "node_definition": {
130
+ "id": mock_node_uuid,
125
131
  "name": "MockNode",
126
132
  "module": module_root + ["events", "tests", "test_event"],
127
133
  },
128
134
  "parent": {
129
135
  "workflow_definition": {
136
+ "id": mock_workflow_uuid,
130
137
  "name": "MockWorkflow",
131
138
  "module": module_root + ["events", "tests", "test_event"],
132
139
  },
@@ -162,6 +169,7 @@ module_root = name_parts[: name_parts.index("events")]
162
169
  "name": "workflow.execution.streaming",
163
170
  "body": {
164
171
  "workflow_definition": {
172
+ "id": mock_workflow_uuid,
165
173
  "name": "MockWorkflow",
166
174
  "module": module_root + ["events", "tests", "test_event"],
167
175
  },
@@ -195,6 +203,7 @@ module_root = name_parts[: name_parts.index("events")]
195
203
  "name": "workflow.execution.fulfilled",
196
204
  "body": {
197
205
  "workflow_definition": {
206
+ "id": mock_workflow_uuid,
198
207
  "name": "MockWorkflow",
199
208
  "module": module_root + ["events", "tests", "test_event"],
200
209
  },
@@ -228,6 +237,7 @@ module_root = name_parts[: name_parts.index("events")]
228
237
  "name": "workflow.execution.rejected",
229
238
  "body": {
230
239
  "workflow_definition": {
240
+ "id": mock_workflow_uuid,
231
241
  "name": "MockWorkflow",
232
242
  "module": module_root + ["events", "tests", "test_event"],
233
243
  },
@@ -262,6 +272,7 @@ module_root = name_parts[: name_parts.index("events")]
262
272
  "name": "node.execution.streaming",
263
273
  "body": {
264
274
  "node_definition": {
275
+ "id": mock_node_uuid,
265
276
  "name": "MockNode",
266
277
  "module": module_root + ["events", "tests", "test_event"],
267
278
  },
@@ -296,6 +307,7 @@ module_root = name_parts[: name_parts.index("events")]
296
307
  "name": "node.execution.fulfilled",
297
308
  "body": {
298
309
  "node_definition": {
310
+ "id": mock_node_uuid,
299
311
  "name": "MockNode",
300
312
  "module": module_root + ["events", "tests", "test_event"],
301
313
  },
@@ -28,6 +28,15 @@ def serialize_type_encoder(obj: type) -> Dict[str, Any]:
28
28
  }
29
29
 
30
30
 
31
+ def serialize_type_encoder_with_id(obj: type) -> Dict[str, Any]:
32
+ if not hasattr(obj, "__id__"):
33
+ raise AttributeError(f"The object of type '{type(obj).__name__}' must have an '__id__' attribute.")
34
+ return {
35
+ "id": getattr(obj, "__id__"),
36
+ **serialize_type_encoder(obj),
37
+ }
38
+
39
+
31
40
  def default_serializer(obj: Any) -> Any:
32
41
  return json.loads(
33
42
  json.dumps(
@@ -38,17 +47,18 @@ def default_serializer(obj: Any) -> Any:
38
47
 
39
48
 
40
49
  class CodeResourceDefinition(UniversalBaseModel):
50
+ id: UUID
41
51
  name: str
42
52
  module: List[str]
43
53
 
44
54
  @staticmethod
45
55
  def encode(obj: type) -> "CodeResourceDefinition":
46
- return CodeResourceDefinition(**serialize_type_encoder(obj))
56
+ return CodeResourceDefinition(**serialize_type_encoder_with_id(obj))
47
57
 
48
58
 
49
59
  VellumCodeResourceDefinition = Annotated[
50
60
  CodeResourceDefinition,
51
- BeforeValidator(lambda d: (d if type(d) is dict else serialize_type_encoder(d))),
61
+ BeforeValidator(lambda d: (d if type(d) is dict else serialize_type_encoder_with_id(d))),
52
62
  ]
53
63
 
54
64
 
@@ -16,7 +16,7 @@ from .node import (
16
16
  NodeExecutionResumedEvent,
17
17
  NodeExecutionStreamingEvent,
18
18
  )
19
- from .types import BaseEvent, default_serializer, serialize_type_encoder
19
+ from .types import BaseEvent, default_serializer, serialize_type_encoder_with_id
20
20
 
21
21
  if TYPE_CHECKING:
22
22
  from vellum.workflows.workflows.base import BaseWorkflow
@@ -27,7 +27,7 @@ class _BaseWorkflowExecutionBody(UniversalBaseModel):
27
27
 
28
28
  @field_serializer("workflow_definition")
29
29
  def serialize_workflow_definition(self, workflow_definition: Type, _info: Any) -> Dict[str, Any]:
30
- return serialize_type_encoder(workflow_definition)
30
+ return serialize_type_encoder_with_id(workflow_definition)
31
31
 
32
32
 
33
33
  class _BaseWorkflowEvent(BaseEvent):
@@ -2,11 +2,30 @@ from functools import cache
2
2
  from typing import Type
3
3
 
4
4
  from vellum.workflows.nodes import BaseNode
5
+ from vellum.workflows.ports.port import Port
5
6
  from vellum.workflows.types.generics import NodeType
6
7
 
7
8
  ADORNMENT_MODULE_NAME = "<adornment>"
8
9
 
9
10
 
11
+ @cache
12
+ def get_unadorned_node(node: Type[BaseNode]) -> Type[BaseNode]:
13
+ wrapped_node = getattr(node, "__wrapped_node__", None)
14
+ if wrapped_node is not None:
15
+ return get_unadorned_node(wrapped_node)
16
+
17
+ return node
18
+
19
+
20
+ @cache
21
+ def get_unadorned_port(port: Port) -> Port:
22
+ unadorned_node = get_unadorned_node(port.node_class)
23
+ if unadorned_node == port.node_class:
24
+ return port
25
+
26
+ return getattr(unadorned_node.Ports, port.name)
27
+
28
+
10
29
  @cache
11
30
  def get_wrapped_node(node: Type[NodeType]) -> Type[BaseNode]:
12
31
  wrapped_node = getattr(node, "__wrapped_node__", None)
@@ -4,6 +4,7 @@ import importlib
4
4
  import inspect
5
5
 
6
6
  from vellum.plugins.utils import load_runtime_plugins
7
+ from vellum.workflows.utils.uuids import uuid4_from_hash
7
8
  from vellum.workflows.workflows.event_filters import workflow_event_filter
8
9
 
9
10
  load_runtime_plugins()
@@ -11,7 +12,7 @@ load_runtime_plugins()
11
12
  from datetime import datetime
12
13
  from functools import lru_cache
13
14
  from threading import Event as ThreadingEvent
14
- from uuid import uuid4
15
+ from uuid import UUID, uuid4
15
16
  from typing import (
16
17
  Any,
17
18
  Callable,
@@ -85,13 +86,17 @@ class _BaseWorkflowMeta(type):
85
86
  if "graph" not in dct:
86
87
  dct["graph"] = set()
87
88
 
88
- return super().__new__(mcs, name, bases, dct)
89
+ cls = super().__new__(mcs, name, bases, dct)
90
+ workflow_class = cast(Type["BaseWorkflow"], cls)
91
+ workflow_class.__id__ = uuid4_from_hash(workflow_class.__qualname__)
92
+ return workflow_class
89
93
 
90
94
 
91
95
  GraphAttribute = Union[Type[BaseNode], Graph, Set[Type[BaseNode]], Set[Graph]]
92
96
 
93
97
 
94
98
  class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkflowMeta):
99
+ __id__: UUID = uuid4_from_hash(__qualname__)
95
100
  graph: ClassVar[GraphAttribute]
96
101
  emitters: List[BaseWorkflowEmitter]
97
102
  resolvers: List[BaseWorkflowResolver]
@@ -1,6 +1,6 @@
1
1
  from typing import TYPE_CHECKING, Type
2
2
 
3
- from vellum.workflows.events.types import CodeResourceDefinition
3
+ from vellum.workflows.events.types import VellumCodeResourceDefinition
4
4
 
5
5
  if TYPE_CHECKING:
6
6
  from vellum.workflows.events.workflow import WorkflowEvent
@@ -47,7 +47,7 @@ def root_workflow_event_filter(workflow_definition: Type["BaseWorkflow"], event:
47
47
  return False
48
48
 
49
49
  event_parent_definition = event.parent.workflow_definition
50
- current_workflow_definition = CodeResourceDefinition.encode(workflow_definition)
50
+ current_workflow_definition = VellumCodeResourceDefinition.encode(workflow_definition)
51
51
 
52
52
  return event_parent_definition.model_dump() == current_workflow_definition.model_dump()
53
53
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.12.1
3
+ Version: 0.12.2
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -20,7 +20,7 @@ vellum_ee/workflows/display/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
20
20
  vellum_ee/workflows/display/base.py,sha256=3ZFUYRNKL24fBqXhKpa_Dq2W1a-a86J20dmJYA3H2eY,1755
21
21
  vellum_ee/workflows/display/nodes/__init__.py,sha256=5XOcZJXYUgaLS55QgRJzyQ_W1tpeprjnYAeYVezqoGw,160
22
22
  vellum_ee/workflows/display/nodes/base_node_display.py,sha256=23PLqcpMe_mYkYdug9PDb6Br7o64Thx9-IhcviKGvGo,6662
23
- vellum_ee/workflows/display/nodes/base_node_vellum_display.py,sha256=E7BFiDv7RdPt_CYhmlgc5ZoQo4JcSQKBGFsAQg0OaJ4,2113
23
+ vellum_ee/workflows/display/nodes/base_node_vellum_display.py,sha256=7F4zQnZQBOTp9turUUS41RaO40Z14m851WOLJHgmHPU,2234
24
24
  vellum_ee/workflows/display/nodes/get_node_display_class.py,sha256=vyKeJAevAXvEAEtWeTEdBZXD3eJQYW_DEXLKVZ5KmYc,1325
25
25
  vellum_ee/workflows/display/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  vellum_ee/workflows/display/nodes/tests/test_base_node_display.py,sha256=QqR3Ly0RNrXwOeLdW5nERDFt0gRPf76n1bPES6o5UN4,1093
@@ -33,7 +33,7 @@ vellum_ee/workflows/display/nodes/vellum/conditional_node.py,sha256=9JjtXTpyC14X
33
33
  vellum_ee/workflows/display/nodes/vellum/error_node.py,sha256=ygTjSjYDI4DtkxADWub5rhBnRWItMKWF6fezBrgpOKA,1979
34
34
  vellum_ee/workflows/display/nodes/vellum/final_output_node.py,sha256=t5iJQVoRT5g-v2IiUb4kFYdvUVKch0zn27016pzDZoo,2761
35
35
  vellum_ee/workflows/display/nodes/vellum/guardrail_node.py,sha256=3TJvHX_Uuf_gr94VkYc_zmNH8I5p71ChIeoAbJZ3ddY,2158
36
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=aU_jZeV0CC3JkIo_LHSh7peLbJEqEaV4odrLPtqzRxI,7375
36
+ vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=E7U4B05-KSlPvTp0nYQTtGPkNa5563VxrNBQmKwvTqw,7267
37
37
  vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py,sha256=x5wiuWbRjxNcPGu8BoBEKHwPeqCpHE-vrGjAdM5TJOs,4721
38
38
  vellum_ee/workflows/display/nodes/vellum/map_node.py,sha256=AqUlItgSZij12qRKguKVmDbbaLuDy3Cdom5uOlJPqrc,3640
39
39
  vellum_ee/workflows/display/nodes/vellum/merge_node.py,sha256=jzO63B9KiEAncnBqmz2ZTcxjmEHozMEe7WnfpcpsQYg,3195
@@ -44,7 +44,7 @@ vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py,sha256=z
44
44
  vellum_ee/workflows/display/nodes/vellum/templating_node.py,sha256=UNYxoE-89agE8ugK0aWg_uN61jPqlC2VSxWHk568sN4,3324
45
45
  vellum_ee/workflows/display/nodes/vellum/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
46
  vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py,sha256=aJfQnIvlrRHVKgQid_gg6VQKkJyPgFnzbvWt9_t0Vz0,3860
47
- vellum_ee/workflows/display/nodes/vellum/try_node.py,sha256=4k9DdjjCkZ_-4qynwg40IipT5Sq2WwgYFFE8WMnMdr0,2612
47
+ vellum_ee/workflows/display/nodes/vellum/try_node.py,sha256=hB8dcGMGkuC95kk9hmZUgHsCLwEA37fHTFXj0JzbRjM,4692
48
48
  vellum_ee/workflows/display/nodes/vellum/utils.py,sha256=3QsKS5Kht2Nod4A18T0bb4filK9AkyK5oImVlViK3l8,4643
49
49
  vellum_ee/workflows/display/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
50
  vellum_ee/workflows/display/tests/test_vellum_workflow_display.py,sha256=TEg3QbdE7rLbEhml9pMWmay--phsekGlfGVhTblxCGE,1727
@@ -70,13 +70,13 @@ vellum_ee/workflows/display/vellum.py,sha256=OSv0ZS50h1zJbunJ9TH7VEWFw-exXdK_Zsd
70
70
  vellum_ee/workflows/display/workflows/__init__.py,sha256=kapXsC67VJcgSuiBMa86FdePG5A9kMB5Pi4Uy1O2ob4,207
71
71
  vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=ydAbFMzcY2LURINZbXYm9BAXZdIa3-7rQ86Kupo7qcA,12804
72
72
  vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=AMxNnTm2z3LIR5rqxoCAfuy37F2FTuSRDVtKUoezO8M,1184
73
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py,sha256=CvxUFudijGW4M7vapm_qrNG4X36PZxzFh6n6qBE9E1Y,17134
73
+ vellum_ee/workflows/display/workflows/vellum_workflow_display.py,sha256=GhIviEMDWNw1p8z20ta08T5PeNCVJs5p2hrOX1uyNxg,17066
74
74
  vellum/__init__.py,sha256=QmGeEPXeFxgkZa849KKK3wH3Y641wyt00Rytfay6KiM,35520
75
75
  vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
76
76
  vellum/client/__init__.py,sha256=o4m7iRZWEV8rP3GkdaztHAjNmjxjWERlarviFoHzuKI,110927
77
77
  vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
78
78
  vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
79
- vellum/client/core/client_wrapper.py,sha256=H2IXjD1b02FWzrMw028nrenbKt081feJ95KpLGbDnFk,1890
79
+ vellum/client/core/client_wrapper.py,sha256=3AlZG0Q4dIs1dgMiXCS_tnLozbk0PAelt6J52g8Tm3k,1890
80
80
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
81
81
  vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
82
82
  vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
@@ -1215,11 +1215,11 @@ vellum/workflows/environment/environment.py,sha256=IwcVSwA51jW1JTN_MAN22UbeAtZhi
1215
1215
  vellum/workflows/errors/__init__.py,sha256=tWGPu5xyAU8gRb8_bl0fL7OfU3wxQ9UH6qVwy4X4P_Q,113
1216
1216
  vellum/workflows/errors/types.py,sha256=mvywC2sXtpRrkDRfTx-O6aXAp0hOFyx27a1tqguKt4g,2493
1217
1217
  vellum/workflows/events/__init__.py,sha256=6pxxceJo2dcaRkWtkDAYlUQZ-PHBQSZytIoyuUK48Qw,759
1218
- vellum/workflows/events/node.py,sha256=QOikR6w5KXJUjnDNF2RhjXRbG7lJySetAoPamyr733Y,5264
1218
+ vellum/workflows/events/node.py,sha256=uHT6If0esgZ3nLjrjmUPTKf3qbjGhoV_x5YKpjDBDcU,5280
1219
1219
  vellum/workflows/events/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1220
- vellum/workflows/events/tests/test_event.py,sha256=EFg34nGpl_LvbHWN5AuiMqH6PetwGF_z0TlETGsn_bU,12725
1221
- vellum/workflows/events/types.py,sha256=7sBSMNstsibqq93Klu4A-GInzo4IB23xWel595Uyi_Y,3077
1222
- vellum/workflows/events/workflow.py,sha256=LW1qjLYCa9mpZjxp6YuDDA0M-q0COBIfLuduP9pOfyo,5224
1220
+ vellum/workflows/events/tests/test_event.py,sha256=izB6Y9U5ROgmHBBpLNUY2navK4-qFp6hdJqJNz6Beek,13350
1221
+ vellum/workflows/events/types.py,sha256=cjRE8WL8tYCFradd9NOGl_H0mN3LiWWnA1uHmyT2Q0Q,3412
1222
+ vellum/workflows/events/workflow.py,sha256=l5tXes0sg7iWaA1ZUE5dtAqNnGQ8iy6trVbOU9meu7U,5240
1223
1223
  vellum/workflows/exceptions.py,sha256=gXQvDL919cK3pwXc8BhLGKmR-YOskYDLvL1zPSSmLS4,579
1224
1224
  vellum/workflows/expressions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1225
1225
  vellum/workflows/expressions/accessor.py,sha256=OFvAHAVABr-k7GceIhtzIurV4OuV_yHft7JPRsq87Es,1472
@@ -1327,7 +1327,7 @@ vellum/workflows/nodes/displayable/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5
1327
1327
  vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py,sha256=lLnXKAUYtgvQ6MpT4GoTrqLtdlyDlUt1pPHrmu-Gf00,4705
1328
1328
  vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py,sha256=4CMwDtXwTaEvFfDpA6j2iLqc7S6IICSkvVZOobEpeps,6954
1329
1329
  vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py,sha256=KqKJtJ0vuNoPuUPMdILmBTt4a2fBBxxun-nmOI7T8jo,2585
1330
- vellum/workflows/nodes/utils.py,sha256=RWQbcc6MgxHNwFjtasY4hzIH8pKe0E3zfVt6eJKGTp4,587
1330
+ vellum/workflows/nodes/utils.py,sha256=EZt7CzJmgQBR_GWFpZr8d-oaoti3tolTd2Cv9wm7dKo,1087
1331
1331
  vellum/workflows/outputs/__init__.py,sha256=AyZ4pRh_ACQIGvkf0byJO46EDnSix1ZCAXfvh-ms1QE,94
1332
1332
  vellum/workflows/outputs/base.py,sha256=a7W6rNSDSawwGAXYjNTF2iHb9lnZu7WFSOagZIyy__k,7976
1333
1333
  vellum/workflows/ports/__init__.py,sha256=bZuMt-R7z5bKwpu4uPW7LlJeePOQWmCcDSXe5frUY5g,101
@@ -1375,10 +1375,10 @@ vellum/workflows/utils/uuids.py,sha256=DFzPv9RCvsKhvdTEIQyfSek2A31D6S_QcmeLPbgrg
1375
1375
  vellum/workflows/utils/vellum_variables.py,sha256=DsjVj_M_vTafpi5OUDs4KNrmbU2n4LR7fcLhuHb67Z4,3123
1376
1376
  vellum/workflows/vellum_client.py,sha256=ODrq_TSl-drX2aezXegf7pizpWDVJuTXH-j6528t75s,683
1377
1377
  vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
1378
- vellum/workflows/workflows/base.py,sha256=jFu_AAyt4IqOrwanyflNnDhgYpX4oTVR5xnow8ynRhg,16811
1379
- vellum/workflows/workflows/event_filters.py,sha256=-uQcMB7IpPd-idMku8f2QNVhPXPFWo6FZLlGjRf8rCo,1996
1380
- vellum_ai-0.12.1.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1381
- vellum_ai-0.12.1.dist-info/METADATA,sha256=m7888sp693GSPQLWUuFa1W1ehpB2orR-RuEqmqpV-SQ,5128
1382
- vellum_ai-0.12.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1383
- vellum_ai-0.12.1.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1384
- vellum_ai-0.12.1.dist-info/RECORD,,
1378
+ vellum/workflows/workflows/base.py,sha256=zpspOEdO5Ye_0ZvN-Wkzv9iQSiF1sD201ba8lhbnPbs,17086
1379
+ vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
1380
+ vellum_ai-0.12.2.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1381
+ vellum_ai-0.12.2.dist-info/METADATA,sha256=alKUy1QGixY3flPix2H1o-GW9kh_xrF5CKtOm5EhJ6I,5128
1382
+ vellum_ai-0.12.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1383
+ vellum_ai-0.12.2.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1384
+ vellum_ai-0.12.2.dist-info/RECORD,,
@@ -1,6 +1,7 @@
1
1
  from uuid import UUID
2
2
  from typing import ClassVar, Dict, Optional
3
3
 
4
+ from vellum.workflows.nodes.utils import get_unadorned_node
4
5
  from vellum.workflows.ports import Port
5
6
  from vellum.workflows.types.generics import NodeType
6
7
  from vellum.workflows.utils.uuids import uuid4_from_hash
@@ -40,6 +41,8 @@ class BaseNodeVellumDisplay(BaseNodeDisplay[NodeType]):
40
41
  return self.get_target_handle_id()
41
42
 
42
43
  def get_source_handle_id(self, port_displays: Dict[Port, PortDisplay]) -> UUID:
43
- default_port = self._node.Ports.default
44
+ unadorned_node = get_unadorned_node(self._node)
45
+ default_port = unadorned_node.Ports.default
46
+
44
47
  default_port_display = port_displays[default_port]
45
48
  return default_port_display.id
@@ -1,9 +1,8 @@
1
1
  from uuid import UUID
2
- from typing import ClassVar, Dict, Generic, List, Optional, Tuple, Type, TypeVar, Union, cast
2
+ from typing import ClassVar, Dict, Generic, List, Optional, Tuple, Type, TypeVar, Union
3
3
 
4
4
  from vellum import PromptBlock, RichTextChildBlock, VellumVariable
5
5
  from vellum.workflows.nodes import InlinePromptNode
6
- from vellum.workflows.references import OutputReference
7
6
  from vellum.workflows.types.core import JsonObject
8
7
  from vellum.workflows.utils.uuids import uuid4_from_hash
9
8
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
@@ -30,8 +29,8 @@ class BaseInlinePromptNodeDisplay(BaseNodeVellumDisplay[_InlinePromptNodeType],
30
29
  node_inputs, prompt_inputs = self._generate_node_and_prompt_inputs(node_id, node, display_context)
31
30
  input_variable_id_by_name = {prompt_input.key: prompt_input.id for prompt_input in prompt_inputs}
32
31
 
33
- _, output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.text)]
34
- _, array_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.results)]
32
+ _, output_display = display_context.node_output_displays[node.Outputs.text]
33
+ _, array_display = display_context.node_output_displays[node.Outputs.results]
35
34
  node_blocks = raise_if_descriptor(node.blocks)
36
35
 
37
36
  return {
@@ -1,11 +1,13 @@
1
1
  from uuid import UUID
2
- from typing import Any, ClassVar, Generic, Optional, TypeVar
2
+ from typing import Any, Callable, ClassVar, Generic, Optional, Type, TypeVar, cast
3
3
 
4
4
  from vellum.workflows.nodes.bases.base import BaseNode
5
5
  from vellum.workflows.nodes.core.try_node.node import TryNode
6
6
  from vellum.workflows.nodes.utils import ADORNMENT_MODULE_NAME, get_wrapped_node
7
7
  from vellum.workflows.types.core import JsonObject
8
+ from vellum.workflows.types.utils import get_original_base
8
9
  from vellum.workflows.utils.uuids import uuid4_from_hash
10
+ from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
9
11
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
10
12
  from vellum_ee.workflows.display.nodes.get_node_display_class import get_node_display_class
11
13
  from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
@@ -54,3 +56,43 @@ class BaseTryNodeDisplay(BaseNodeVellumDisplay[_TryNodeType], Generic[_TryNodeTy
54
56
  serialized_node_definition["name"] = node.__name__
55
57
 
56
58
  return serialized_node
59
+
60
+ @classmethod
61
+ def wrap(cls, error_output_id: Optional[UUID] = None) -> Callable[..., Type["BaseTryNodeDisplay"]]:
62
+ _error_output_id = error_output_id
63
+
64
+ NodeDisplayType = TypeVar("NodeDisplayType", bound=BaseNodeDisplay)
65
+
66
+ def decorator(inner_cls: Type[NodeDisplayType]) -> Type[NodeDisplayType]:
67
+ node_class = inner_cls.infer_node_class()
68
+ wrapped_node_class = cast(Type[BaseNode], node_class.__wrapped_node__)
69
+
70
+ # Mypy gets mad about dynamic parameter types like this, but it's fine
71
+ class TryNodeDisplay(BaseTryNodeDisplay[node_class]): # type: ignore[valid-type]
72
+ error_output_id = _error_output_id
73
+
74
+ setattr(inner_cls, "__adorned_by__", TryNodeDisplay)
75
+
76
+ # We must edit the node display class to use __wrapped_node__ everywhere it
77
+ # references the adorned node class, which is three places:
78
+
79
+ # 1. The node display class' parameterized type
80
+ original_base_node_display = get_original_base(inner_cls)
81
+ original_base_node_display.__args__ = (wrapped_node_class,)
82
+ inner_cls._node_display_registry[wrapped_node_class] = inner_cls
83
+
84
+ # 2. The node display class' output displays
85
+ old_outputs = list(inner_cls.output_display.keys())
86
+ for old_output in old_outputs:
87
+ new_output = getattr(wrapped_node_class.Outputs, old_output.name)
88
+ inner_cls.output_display[new_output] = inner_cls.output_display.pop(old_output)
89
+
90
+ # 3. The node display class' port displays
91
+ old_ports = list(inner_cls.port_displays.keys())
92
+ for old_port in old_ports:
93
+ new_port = getattr(wrapped_node_class.Ports, old_port.name)
94
+ inner_cls.port_displays[new_port] = inner_cls.port_displays.pop(old_port)
95
+
96
+ return inner_cls
97
+
98
+ return decorator
@@ -6,7 +6,7 @@ from vellum.workflows.descriptors.base import BaseDescriptor
6
6
  from vellum.workflows.edges import Edge
7
7
  from vellum.workflows.nodes.bases import BaseNode
8
8
  from vellum.workflows.nodes.displayable.final_output_node import FinalOutputNode
9
- from vellum.workflows.nodes.utils import get_wrapped_node, has_wrapped_node
9
+ from vellum.workflows.nodes.utils import get_unadorned_node, get_unadorned_port, get_wrapped_node, has_wrapped_node
10
10
  from vellum.workflows.ports import Port
11
11
  from vellum.workflows.references import WorkflowInputReference
12
12
  from vellum.workflows.references.output import OutputReference
@@ -352,17 +352,12 @@ class VellumWorkflowDisplay(
352
352
  port_displays: Dict[Port, PortDisplay],
353
353
  overrides: Optional[EdgeVellumDisplayOverrides] = None,
354
354
  ) -> EdgeVellumDisplay:
355
- source_node = edge.from_port.node_class
356
- target_node = edge.to_node
357
-
358
- if has_wrapped_node(source_node):
359
- source_node = get_wrapped_node(source_node)
360
-
361
- if has_wrapped_node(target_node):
362
- target_node = get_wrapped_node(target_node)
355
+ source_node = get_unadorned_node(edge.from_port.node_class)
356
+ target_node = get_unadorned_node(edge.to_node)
363
357
 
364
358
  source_node_id = node_displays[source_node].node_id
365
- source_handle_id = port_displays[edge.from_port].id
359
+ from_port = get_unadorned_port(edge.from_port)
360
+ source_handle_id = port_displays[from_port].id
366
361
 
367
362
  target_node_display = node_displays[target_node]
368
363
  target_node_id = target_node_display.node_id