vellum-ai 1.1.4__py3-none-any.whl → 1.2.0__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 (32) hide show
  1. vellum/client/core/client_wrapper.py +2 -2
  2. vellum/workflows/emitters/vellum_emitter.py +5 -0
  3. vellum/workflows/sandbox.py +22 -5
  4. vellum/workflows/state/context.py +8 -52
  5. vellum/workflows/workflows/base.py +1 -1
  6. {vellum_ai-1.1.4.dist-info → vellum_ai-1.2.0.dist-info}/METADATA +1 -1
  7. {vellum_ai-1.1.4.dist-info → vellum_ai-1.2.0.dist-info}/RECORD +32 -32
  8. vellum_ee/workflows/display/nodes/base_node_display.py +5 -5
  9. vellum_ee/workflows/display/nodes/tests/test_base_node_display.py +1 -1
  10. vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +4 -0
  11. vellum_ee/workflows/display/nodes/vellum/retry_node.py +1 -1
  12. vellum_ee/workflows/display/nodes/vellum/tests/test_retry_node.py +1 -1
  13. vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py +75 -1
  14. vellum_ee/workflows/display/nodes/vellum/try_node.py +1 -1
  15. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +9 -9
  16. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +59 -9
  17. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py +3 -3
  18. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py +14 -15
  19. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py +58 -3
  20. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +1 -1
  21. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_prompt_node_serialization.py +4 -0
  22. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +1 -1
  23. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py +6 -3
  24. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py +5 -2
  25. vellum_ee/workflows/display/types.py +13 -2
  26. vellum_ee/workflows/display/utils/expressions.py +5 -1
  27. vellum_ee/workflows/display/workflows/base_workflow_display.py +35 -0
  28. vellum_ee/workflows/display/workflows/tests/test_workflow_display.py +44 -2
  29. vellum_ee/workflows/tests/test_serialize_module.py +31 -0
  30. {vellum_ai-1.1.4.dist-info → vellum_ai-1.2.0.dist-info}/LICENSE +0 -0
  31. {vellum_ai-1.1.4.dist-info → vellum_ai-1.2.0.dist-info}/WHEEL +0 -0
  32. {vellum_ai-1.1.4.dist-info → vellum_ai-1.2.0.dist-info}/entry_points.txt +0 -0
@@ -27,10 +27,10 @@ class BaseClientWrapper:
27
27
 
28
28
  def get_headers(self) -> typing.Dict[str, str]:
29
29
  headers: typing.Dict[str, str] = {
30
- "User-Agent": "vellum-ai/1.1.4",
30
+ "User-Agent": "vellum-ai/1.2.0",
31
31
  "X-Fern-Language": "Python",
32
32
  "X-Fern-SDK-Name": "vellum-ai",
33
- "X-Fern-SDK-Version": "1.1.4",
33
+ "X-Fern-SDK-Version": "1.2.0",
34
34
  **(self.get_custom_headers() or {}),
35
35
  }
36
36
  if self._api_version is not None:
@@ -11,6 +11,8 @@ from vellum.workflows.state.base import BaseState
11
11
 
12
12
  logger = logging.getLogger(__name__)
13
13
 
14
+ DISALLOWED_EVENTS = {"workflow.execution.streaming", "node.execution.streaming"}
15
+
14
16
 
15
17
  class VellumEmitter(BaseWorkflowEmitter):
16
18
  """
@@ -53,6 +55,9 @@ class VellumEmitter(BaseWorkflowEmitter):
53
55
  if not self._context:
54
56
  return
55
57
 
58
+ if event.name in DISALLOWED_EVENTS:
59
+ return
60
+
56
61
  try:
57
62
  event_data = default_serializer(event)
58
63
 
@@ -1,4 +1,4 @@
1
- from typing import Generic, Sequence
1
+ from typing import Generic, Optional, Sequence
2
2
 
3
3
  import dotenv
4
4
 
@@ -10,12 +10,29 @@ from vellum.workflows.workflows.event_filters import root_workflow_event_filter
10
10
 
11
11
 
12
12
  class WorkflowSandboxRunner(Generic[WorkflowType]):
13
- def __init__(self, workflow: WorkflowType, inputs: Sequence[BaseInputs]):
14
- if not inputs:
15
- raise ValueError("Inputs are required to have at least one defined inputs")
13
+ def __init__(
14
+ self,
15
+ workflow: WorkflowType,
16
+ inputs: Optional[Sequence[BaseInputs]] = None, # DEPRECATED - remove in v2.0.0
17
+ dataset: Optional[Sequence[BaseInputs]] = None,
18
+ ):
19
+ if dataset is not None and inputs is not None:
20
+ raise ValueError(
21
+ "Cannot specify both 'dataset' and 'inputs' parameters. " "Use 'dataset' as 'inputs' is deprecated."
22
+ )
23
+
24
+ if dataset is not None:
25
+ actual_inputs = dataset
26
+ elif inputs is not None:
27
+ actual_inputs = inputs
28
+ else:
29
+ raise ValueError("Either 'dataset' or 'inputs' parameter is required")
30
+
31
+ if not actual_inputs:
32
+ raise ValueError("Dataset/inputs are required to have at least one defined input")
16
33
 
17
34
  self._workflow = workflow
18
- self._inputs = inputs
35
+ self._inputs = actual_inputs
19
36
 
20
37
  dotenv.load_dotenv()
21
38
  self._logger = load_logger()
@@ -1,12 +1,10 @@
1
1
  from functools import cached_property
2
- import inspect
3
2
  from queue import Queue
4
3
  from uuid import uuid4
5
4
  from typing import TYPE_CHECKING, Dict, List, Optional, Type
6
5
 
7
6
  from vellum import Vellum
8
- from vellum.workflows.context import ExecutionContext, get_execution_context, set_execution_context
9
- from vellum.workflows.emitters.vellum_emitter import VellumEmitter
7
+ from vellum.workflows.context import ExecutionContext, get_execution_context
10
8
  from vellum.workflows.events.types import ExternalParentContext
11
9
  from vellum.workflows.nodes.mocks import MockNodeExecution, MockNodeExecutionArg
12
10
  from vellum.workflows.outputs.base import BaseOutputs
@@ -14,7 +12,6 @@ from vellum.workflows.references.constant import ConstantValueReference
14
12
  from vellum.workflows.vellum_client import create_vellum_client
15
13
 
16
14
  if TYPE_CHECKING:
17
- from vellum.workflows.emitters.base import BaseWorkflowEmitter
18
15
  from vellum.workflows.events.workflow import WorkflowEvent
19
16
 
20
17
 
@@ -29,36 +26,15 @@ class WorkflowContext:
29
26
  self._vellum_client = vellum_client
30
27
  self._event_queue: Optional[Queue["WorkflowEvent"]] = None
31
28
  self._node_output_mocks_map: Dict[Type[BaseOutputs], List[MockNodeExecution]] = {}
32
- # Clone the current thread-local execution context to avoid mutating global state
33
- current_execution_context = get_execution_context()
34
-
35
- # Resolve parent_context preference: provided > current > new external
36
- resolved_parent_context = (
37
- execution_context.parent_context
38
- if execution_context is not None and execution_context.parent_context is not None
39
- else current_execution_context.parent_context
40
- )
41
- if resolved_parent_context is None:
42
- resolved_parent_context = ExternalParentContext(span_id=uuid4())
43
-
44
- # Resolve trace_id preference: provided (if set) > current (if set) > new uuid
45
- if execution_context is not None and int(execution_context.trace_id) != 0:
46
- resolved_trace_id = execution_context.trace_id
47
- elif int(current_execution_context.trace_id) != 0:
48
- resolved_trace_id = current_execution_context.trace_id
49
- else:
50
- resolved_trace_id = uuid4()
29
+ self._execution_context = get_execution_context()
51
30
 
52
- # Construct a single, resolved execution context for this workflow instance
53
- self._execution_context = ExecutionContext(
54
- parent_context=resolved_parent_context,
55
- trace_id=resolved_trace_id,
56
- )
31
+ if execution_context is not None:
32
+ self._execution_context.trace_id = execution_context.trace_id
33
+ if execution_context.parent_context is not None:
34
+ self._execution_context.parent_context = execution_context.parent_context
57
35
 
58
- # Ensure the thread-local context has a parent_context for nodes that read it directly
59
- if current_execution_context.parent_context is None:
60
- current_execution_context.parent_context = resolved_parent_context
61
- set_execution_context(current_execution_context)
36
+ if self._execution_context.parent_context is None:
37
+ self._execution_context.parent_context = ExternalParentContext(span_id=uuid4())
62
38
 
63
39
  self._generated_files = generated_files
64
40
 
@@ -128,26 +104,6 @@ class WorkflowContext:
128
104
  # For custom domains, assume the same pattern: api.* -> app.*
129
105
  return api_url.replace("api.", "app.", 1)
130
106
 
131
- def get_emitters_for_workflow(self) -> List["BaseWorkflowEmitter"]:
132
- """
133
- Get the default emitters that should be attached to workflows using this context.
134
-
135
- Returns:
136
- List of emitters, including VellumEmitter if monitoring is enabled.
137
- """
138
- try:
139
- frame = inspect.currentframe()
140
- caller = frame.f_back if frame else None
141
- if caller and "self" in caller.f_locals:
142
- workflow_instance = caller.f_locals["self"]
143
- class_level_emitters = getattr(workflow_instance.__class__, "emitters", None)
144
- if isinstance(class_level_emitters, list) and len(class_level_emitters) > 0:
145
- return class_level_emitters
146
- except Exception:
147
- pass
148
-
149
- return [VellumEmitter()]
150
-
151
107
  def _emit_subworkflow_event(self, event: "WorkflowEvent") -> None:
152
108
  if self._event_queue:
153
109
  self._event_queue.put(event)
@@ -241,7 +241,7 @@ class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
241
241
  ):
242
242
  self._parent_state = parent_state
243
243
  self._context = context or WorkflowContext()
244
- self.emitters = emitters or self._context.get_emitters_for_workflow()
244
+ self.emitters = emitters or (self.emitters if hasattr(self, "emitters") else [])
245
245
  self.resolvers = resolvers or (self.resolvers if hasattr(self, "resolvers") else [])
246
246
  self._store = store or Store()
247
247
  self._execution_context = self._context.execution_context
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 1.1.4
3
+ Version: 1.2.0
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -28,10 +28,10 @@ vellum_ee/workflows/display/editor/__init__.py,sha256=MSAgY91xCEg2neH5d8jXx5wRdR
28
28
  vellum_ee/workflows/display/editor/types.py,sha256=x-tOOCJ6CF4HmiKDfCmcc3bOVfc1EBlP5o6u5WEfLoY,567
29
29
  vellum_ee/workflows/display/exceptions.py,sha256=Oys39dHoW-s-1dnlRSZxTntMq8_macj-b2CT_6dqzJs,355
30
30
  vellum_ee/workflows/display/nodes/__init__.py,sha256=jI1aPBQf8DkmrYoZ4O-wR1duqZByOf5mDFmo_wFJPE4,307
31
- vellum_ee/workflows/display/nodes/base_node_display.py,sha256=oJJiNmF9na2rS5PMMWZLwbajJkssEeBCESDmmz9jy2s,17933
31
+ vellum_ee/workflows/display/nodes/base_node_display.py,sha256=chHNgngguwtjUAf3uJR6FF4TdcYAmkRHLBJRP4WfPW4,17961
32
32
  vellum_ee/workflows/display/nodes/get_node_display_class.py,sha256=jI_kUi9LnNLDpY63QtlC4TfN8P571VN4LpzH0I1ZtLk,1149
33
33
  vellum_ee/workflows/display/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- vellum_ee/workflows/display/nodes/tests/test_base_node_display.py,sha256=Z4Mf7xLCNiblSbpKI0BrV5modQr-ZcFzhfir_OSyTTs,2997
34
+ vellum_ee/workflows/display/nodes/tests/test_base_node_display.py,sha256=wBoCqULS4XO3s9Vwhd9v4g10opfBFqeZgRqB8CoFz0c,3015
35
35
  vellum_ee/workflows/display/nodes/types.py,sha256=St1BB6no528OyELGiyRabWao0GGw6mLhstQAvEACbGk,247
36
36
  vellum_ee/workflows/display/nodes/utils.py,sha256=sloya5TpXsnot1HURc9L51INwflRqUzHxRVnCS9Cd-4,973
37
37
  vellum_ee/workflows/display/nodes/vellum/__init__.py,sha256=nUIgH2s0-7IbQRNrBhLPyRNe8YIrx3Yo9HeeW-aXXFk,1668
@@ -42,13 +42,13 @@ vellum_ee/workflows/display/nodes/vellum/conditional_node.py,sha256=OEw8QRPliL4P
42
42
  vellum_ee/workflows/display/nodes/vellum/error_node.py,sha256=YhMsi2TG1zSR8E7IpxzzSncOyVLcvqTuGa3mr4RqHd8,2364
43
43
  vellum_ee/workflows/display/nodes/vellum/final_output_node.py,sha256=zo-nalsuayMqeb2GwR2OB9SFK3y2U5aG-rtwrsjdasQ,3089
44
44
  vellum_ee/workflows/display/nodes/vellum/guardrail_node.py,sha256=IniO5KvO0Rw9zghFg3RFvbXBTv6Zi1iuQhaA1DLazqU,2331
45
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=9zLM81RU2FHNaKcrtZkQ-Wez5IaSJ1HuxCBC_BM4CZI,11094
45
+ vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=6gbDSw1N74gATXkPvRNSZFd__OncCJP0PPgT-timzwA,11259
46
46
  vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py,sha256=f7MeoxgKrdyb1dSJsvdDtZPlp1J2Pa4njPvN3qHVktA,6028
47
47
  vellum_ee/workflows/display/nodes/vellum/map_node.py,sha256=uaZ2wcZR1J9C9iI0QWAsgNK9IlcuCz1808oxXmiYsLY,3908
48
48
  vellum_ee/workflows/display/nodes/vellum/merge_node.py,sha256=RTP_raQWL8ZKoRKLpxLfpyXzw61TZeTCkTuM1uRLIkI,3274
49
49
  vellum_ee/workflows/display/nodes/vellum/note_node.py,sha256=6xf8MJ684KecKPJrGlCJuJYLPtYImXmqN85Y_6KPjW4,1141
50
50
  vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py,sha256=cT5qT7Nd2v6rSsIErpSAWaxta7txGOSFOZz2AQYQmWE,3536
51
- vellum_ee/workflows/display/nodes/vellum/retry_node.py,sha256=Gos8F1yKN69GmegDO2q3NlGTamibd4rpuTasSU0mK8c,3281
51
+ vellum_ee/workflows/display/nodes/vellum/retry_node.py,sha256=3tkrZu7LczrD6KwdtU3g3xGOyVR3KKSbG5_H3Lbqvho,3274
52
52
  vellum_ee/workflows/display/nodes/vellum/search_node.py,sha256=bF07csUFSQlAeOayPPws5pz3tBTp1PdwgHb8WItgXmY,12319
53
53
  vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py,sha256=wr2MaqoGFtkL1o7B-4GXgF1gEEOTWsUEiX8l_g7e1qs,2958
54
54
  vellum_ee/workflows/display/nodes/vellum/templating_node.py,sha256=TdIJWh2l8p4tw7ejRexGOFQKnviirUqie3WYwsrVQ4g,3339
@@ -60,34 +60,34 @@ vellum_ee/workflows/display/nodes/vellum/tests/test_inline_subworkflow_node.py,s
60
60
  vellum_ee/workflows/display/nodes/vellum/tests/test_note_node.py,sha256=uiMB0cOxKZzos7YKnj4ef4DFa2bOvZJWIv-hfbUV6Go,1218
61
61
  vellum_ee/workflows/display/nodes/vellum/tests/test_prompt_deployment_node.py,sha256=G-qJyTNJkpqJiEZ3kCJl86CXJINLeFyf2lM0bQHCCOs,3822
62
62
  vellum_ee/workflows/display/nodes/vellum/tests/test_prompt_node.py,sha256=h3rXIfB349w11cMgNpqEWCI3ucTsTb30cWskXN8FoV0,14053
63
- vellum_ee/workflows/display/nodes/vellum/tests/test_retry_node.py,sha256=h93ysolmbo2viisyhRnXKHPxiDK0I_dSAbYoHFYIoO4,1953
63
+ vellum_ee/workflows/display/nodes/vellum/tests/test_retry_node.py,sha256=WyqX_g-jN4BOVHIto_HDRVb-uWCmDTaiCwHho4uYKOM,1954
64
64
  vellum_ee/workflows/display/nodes/vellum/tests/test_search_node.py,sha256=KvByxgbUkVyfPIVxTUBUk6a92JiJMi8eReZWxzfPExU,3864
65
65
  vellum_ee/workflows/display/nodes/vellum/tests/test_subworkflow_deployment_node.py,sha256=BUzHJgjdWnPeZxjFjHfDBKnbFjYjnbXPjc-1hne1B2Y,3965
66
66
  vellum_ee/workflows/display/nodes/vellum/tests/test_templating_node.py,sha256=LSk2gx9TpGXbAqKe8dggQW8yJZqj-Cf0EGJFeGGlEcw,3321
67
- vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py,sha256=KF31033chAPfMOC_YOWJH_92ZoNfCdavNWzrEeB0QUc,13819
67
+ vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py,sha256=CPKDOM5Qzk4ETP_onbEmUmEqzNYPru_OgsQG2LAS_Vg,16430
68
68
  vellum_ee/workflows/display/nodes/vellum/tests/test_try_node.py,sha256=Khjsb53PKpZuyhKoRMgKAL45eGp5hZqXvHmVeQWRw4w,2289
69
69
  vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py,sha256=rHybfUAWwa0LlstQTNthGb-zYXrUCLADFtn_4SGsbw8,4807
70
- vellum_ee/workflows/display/nodes/vellum/try_node.py,sha256=z9Omo676RRc7mQjLoL7hjiHhUj0OWVLhrrb97YTN4QA,4086
70
+ vellum_ee/workflows/display/nodes/vellum/try_node.py,sha256=47fOnSCEFnY8th9m2yTYlgnoUuzgyRZdjg-SXwn--lk,4079
71
71
  vellum_ee/workflows/display/nodes/vellum/utils.py,sha256=oICunzyaXPs0tYnW5zH1r93Bx35MSH7mcD-n0DEWRok,4978
72
72
  vellum_ee/workflows/display/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
73
  vellum_ee/workflows/display/tests/test_base_workflow_display.py,sha256=NTtZltrBqA0BlbDvCOJaBWABMmns74StnisA9icBZ8U,10602
74
74
  vellum_ee/workflows/display/tests/workflow_serialization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
75
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
76
  vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py,sha256=Y-ajeT65b5varmrZCw6L3hir4hJCFq-eO0jZfRcrs7g,1886
77
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py,sha256=aEmF6zpmmHdFgiG4V81EweOk5qO6cfukR782dYSE960,14060
78
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py,sha256=DFNp_iUxlyE-zCJBH9ab3e1jQEK-NSE9M2CQd4NCjY8,24853
79
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py,sha256=s6_mnk0pkztU59wYpSfOFpMhAJaRjmyfxM6WJGtnD4Y,6456
80
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py,sha256=PkSgghJDz0fpDB72HHPjLjo8LkZk-HpUkCQzRLX-iVw,40611
81
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py,sha256=dsJr8I9AdPwMOGszirfNDzZP2Ychd94aAKuPXAzknMk,4632
77
+ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py,sha256=bD9AtBo7Pz1Drbh420NR0VSiHBfExw_UtNRPCiAqki0,13967
78
+ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py,sha256=iqTbPYVSrMgIls7vKdPgr7ZEbdpztDjlOWvexPU-zqc,26240
79
+ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py,sha256=O1CIKMmRTaMaT3IhjwCAiMz1ZThPg9lAUbSiZkx_E8c,6321
80
+ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py,sha256=fPXcX-tWQ0UMuEyOFAylgi7pWiE7lZWk9vrShlTExik,40053
81
+ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py,sha256=FLvcD8eoABHUPv08oSpIp_P-65sw2gl4whMXEJJj4f8,6785
82
82
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py,sha256=a05Uh47ZRyy7P2ffZC3yieplFGqmlnjx1sGwY80ZLVU,16189
83
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py,sha256=B4DC2e5nqEk5NZeUwR4vKmBoEyToHkAuq4cCqbsidFo,29708
83
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py,sha256=moLDV23iXN7ngg6DRJqcttWE2v2UfziLIMUZ_2Amjp0,29709
84
84
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py,sha256=oKO8KGlkl505TSW5v0retJF4FS8TfwxxuAzqY9Adr8k,53608
85
85
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_default_state_serialization.py,sha256=E1ww97BFoGbnRkxf84TScat5NQhP8nLVrdaOlpGnSKU,8615
86
86
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_error_node_serialization.py,sha256=w1BYEZXIMjWmcKGQXzhelHnKFlEAXmsgjkI9fcgqKXA,5850
87
87
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_generic_node_serialization.py,sha256=-T0cd2jx1bC0ZNtAESF78fnYD_0nOqo8zMMLwRHUTRM,6227
88
88
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_guardrail_node_serialization.py,sha256=PZ9Yec8D6e9wM2kh5eWtNvK5BghTf1RdvoSW5_pw3FM,7384
89
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_prompt_node_serialization.py,sha256=vVqxXHieRUPP1Rt4ITnjMxuGU52WBfifoEzPyHQnd7w,25618
90
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py,sha256=3Djct7lIr2TPW-wDd_t6eoNdsE0hBOj9OwKWRroXMUo,21659
89
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_prompt_node_serialization.py,sha256=zOv-CzFZs_9NqlINQ7hzJmd4o8ArDBKB7Eyr1Rfd-BU,25767
90
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py,sha256=cCfOGFe1TL8X9-gorbHA0xND3_OuQtKUCGWkYukNQ14,21660
91
91
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py,sha256=91u9FWLErrNGfUkZ22ifk6IazGtaYoDFbZYjhxEESgI,16579
92
92
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py,sha256=rtkAQw5awOFX3pWh0qz3f766-tTnPhToGsXVSHO4M4U,8352
93
93
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_prompt_deployment_serialization.py,sha256=RgJw9lwI7ihqngEbdWbxfIsO1q0asi2JrBx1PRebndU,21076
@@ -96,27 +96,27 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_
96
96
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py,sha256=V8b6gKghLlO7PJI8xeNdnfn8aII0W_IFQvSQBQM62UQ,7721
97
97
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py,sha256=hDWtKXmGI1CKhTwTNqpu_d5RkE5n7SolMLtgd87KqTI,3856
98
98
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_composio_serialization.py,sha256=AUfULtIangNYkvLH3jd2Ar8X5ulW4tGmezeCfMmXFUU,3697
99
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py,sha256=4t1lkN2nsZF6lFqP6QnskUQWJlhasF8C2_f6atzk8ZY,26298
99
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py,sha256=Sg82qV5NCzQDy-RD90hA6QaHgFHOq6ESNkbWXygsnNw,26367
100
100
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_mcp_serialization.py,sha256=9ORex-okcpwbbkxEDJyyRlbPid6zLSDduK0fBfrp8kk,2415
101
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py,sha256=B0rDsCvO24qPp0gkmj8SdTDY5CxZYkvKwknsKBuAPyA,10017
101
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py,sha256=-7NvpYUZEl2T15AS9MPt_scyhKmUmS3wEPa320sgWOI,10085
102
102
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_workflow_deployment_serialization.py,sha256=XIZZr5POo2NLn2uEWm9EC3rejeBMoO4X-JtzTH6mvp4,4074
103
103
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py,sha256=pLCyMScV88DTBXRH7jXaXOEA1GBq8NIipCUFwIAWnwI,2771
104
104
  vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py,sha256=J4ouI8KxbMfxQP2Zq_9cWMGYgbjCWmKzjCJEtnSJb0I,5829
105
105
  vellum_ee/workflows/display/tests/workflow_serialization/test_workflow_input_parameterization_error.py,sha256=vAdmn3YTBDpo55znbydQxsgg9ASqHcvsUPwiBR_7wfo,1461
106
- vellum_ee/workflows/display/types.py,sha256=qRSh7HstBjcAft6dIrij9dLZTanlRWhNwDFfggqJXzs,3174
106
+ vellum_ee/workflows/display/types.py,sha256=cyZruu4sXAdHjwuFc7dydM4DcFNf-pp_CmulXItxac4,3679
107
107
  vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
108
108
  vellum_ee/workflows/display/utils/auto_layout.py,sha256=f4GiLn_LazweupfqTpubcdtdfE_vrOcmZudSsnYIY9E,3906
109
109
  vellum_ee/workflows/display/utils/exceptions.py,sha256=LSwwxCYNxFkf5XMUcFkaZKpQ13OSrI7y_bpEUwbKVk0,169
110
- vellum_ee/workflows/display/utils/expressions.py,sha256=vzytRJ46iGHgOEiBio05EZ0XgXSSdEazRS37S4EYVhQ,16601
110
+ vellum_ee/workflows/display/utils/expressions.py,sha256=EPpdnG4esGVjQVYYWJT1G5LWRLhWN_s45LIPQvy_ge4,16772
111
111
  vellum_ee/workflows/display/utils/registry.py,sha256=fWIm5Jj-10gNFjgn34iBu4RWv3Vd15ijtSN0V97bpW8,1513
112
112
  vellum_ee/workflows/display/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
113
  vellum_ee/workflows/display/utils/tests/test_auto_layout.py,sha256=vfXI769418s9vda5Gb5NFBH747WMOwSgHRXeLCTLVm8,2356
114
114
  vellum_ee/workflows/display/utils/vellum.py,sha256=mtoXmSYwR7rvrq-d6CzCW_auaJXTct0Mi1F0xpRCiNQ,5627
115
115
  vellum_ee/workflows/display/vellum.py,sha256=J2mdJZ1sdLW535DDUkq_Vm8Z572vhuxHxVZF9deKSdk,391
116
116
  vellum_ee/workflows/display/workflows/__init__.py,sha256=JTB9ObEV3l4gGGdtfBHwVJtTTKC22uj-a-XjTVwXCyA,148
117
- vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=ysOq1_con5SvdaeCMeECWEVC1qJzSBTIKA_lJNU0zqQ,41412
117
+ vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=StflRnfj2GPYyvg3-kZvzPoNkw5a8hpSjlaMQBzEnAY,43035
118
118
  vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=gxz76AeCqgAZ9D2lZeTiZzxY9eMgn3qOSfVgiqYcOh8,2028
119
- vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=9CkgKbM_zgq0l2bwst1hLFGyOigpjsBO4ZU6qSMXND4,36027
119
+ vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=pb7BTH-ivRnya1LQU3j-MApWk_m8POpPNOdD0oEK82A,37847
120
120
  vellum_ee/workflows/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
121
121
  vellum_ee/workflows/server/virtual_file_loader.py,sha256=7JphJcSO3H85qiC2DpFfBWjC3JjrbRmoynBC6KKHVsA,2710
122
122
  vellum_ee/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -139,7 +139,7 @@ vellum_ee/workflows/tests/local_workflow/nodes/final_output.py,sha256=ZX7zBv87zi
139
139
  vellum_ee/workflows/tests/local_workflow/nodes/templating_node.py,sha256=NQwFN61QkHfI3Vssz-B0NKGfupK8PU0FDSAIAhYBLi0,325
140
140
  vellum_ee/workflows/tests/local_workflow/workflow.py,sha256=A4qOzOPNwePYxWbcAgIPLsmrVS_aVEZEc-wULSv787Q,393
141
141
  vellum_ee/workflows/tests/test_display_meta.py,sha256=PkXJVnMZs9GNooDkd59n4YTBAX3XGPQWeSSVbhehVFM,5112
142
- vellum_ee/workflows/tests/test_serialize_module.py,sha256=EVrCRAP0lpvd0GIDlg2tnGfJzDNooNDXPfGFPLAqmbI,1870
142
+ vellum_ee/workflows/tests/test_serialize_module.py,sha256=lk-4dVnG2HcxxywBXxDR1ieH8D9RJt4lvchoZhtQPdU,2892
143
143
  vellum_ee/workflows/tests/test_server.py,sha256=SsOkS6sGO7uGC4mxvk4iv8AtcXs058P9hgFHzTWmpII,14519
144
144
  vellum_ee/workflows/tests/test_virtual_files.py,sha256=TJEcMR0v2S8CkloXNmCHA0QW0K6pYNGaIjraJz7sFvY,2762
145
145
  vellum/__init__.py,sha256=iqkCA7SoYec2cOIyNBQeu7f0reFyxwR4zlSAYg71ncM,43613
@@ -147,7 +147,7 @@ vellum/client/README.md,sha256=gxc7JlJRBrBZpN5LHa2ORxYTRHFLPnWmnIugN8pmQh4,5600
147
147
  vellum/client/__init__.py,sha256=NEcLUhKRIK0OGGXTSQbarRaacFkJWFmM5iY4F9lgIDI,72131
148
148
  vellum/client/core/__init__.py,sha256=lTcqUPXcx4112yLDd70RAPeqq6tu3eFMe1pKOqkW9JQ,1562
149
149
  vellum/client/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
150
- vellum/client/core/client_wrapper.py,sha256=6vp_q4aKby-T0ukw9WHtdpLBDqY6TQ7mpOcJmVsaiE4,2840
150
+ vellum/client/core/client_wrapper.py,sha256=TZs53rWMa0VP-FbcYs869Qj_v3-6RgMw_JgLuJoBY0w,2840
151
151
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
152
152
  vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
153
153
  vellum/client/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
@@ -1598,7 +1598,7 @@ vellum/workflows/edges/__init__.py,sha256=wSkmAnz9xyi4vZwtDbKxwlplt2skD7n3NsxkvR
1598
1598
  vellum/workflows/edges/edge.py,sha256=N0SnY3gKVuxImPAdCbPMPlHJIXbkQ3fwq_LbJRvVMFc,677
1599
1599
  vellum/workflows/emitters/__init__.py,sha256=d9QFOI3eVg6rzpSFLvrjkDYXWikf1tcp3ruTRa2Boyc,143
1600
1600
  vellum/workflows/emitters/base.py,sha256=Tcp13VMB-GMwEJdl-6XTPckspdOdwpMgBx22-PcQxds,892
1601
- vellum/workflows/emitters/vellum_emitter.py,sha256=xiVlqe3B5fTR-e48nuneeodN1tkrBt0QQa0o9JHdyWg,5077
1601
+ vellum/workflows/emitters/vellum_emitter.py,sha256=c84BNgXkpOZDZglRz26IhmQtLFwk3DnRHwqOmf4GHIY,5223
1602
1602
  vellum/workflows/environment/__init__.py,sha256=TJz0m9dwIs6YOwCTeuN0HHsU-ecyjc1OJXx4AFy83EQ,121
1603
1603
  vellum/workflows/environment/environment.py,sha256=Ck3RPKXJvtMGx_toqYQQQF-ZwXm5ijVwJpEPTeIJ4_Q,471
1604
1604
  vellum/workflows/errors/__init__.py,sha256=tWGPu5xyAU8gRb8_bl0fL7OfU3wxQ9UH6qVwy4X4P_Q,113
@@ -1802,10 +1802,10 @@ vellum/workflows/resolvers/__init__.py,sha256=eH6hTvZO4IciDaf_cf7aM2vs-DkBDyJPyc
1802
1802
  vellum/workflows/resolvers/base.py,sha256=WHra9LRtlTuB1jmuNqkfVE2JUgB61Cyntn8f0b0WZg4,411
1803
1803
  vellum/workflows/runner/__init__.py,sha256=i1iG5sAhtpdsrlvwgH6B-m49JsINkiWyPWs8vyT-bqM,72
1804
1804
  vellum/workflows/runner/runner.py,sha256=sADrp593ia4auJ8fIP6jc5na3b5WaTvvBdjpkTthboY,36929
1805
- vellum/workflows/sandbox.py,sha256=GVJzVjMuYzOBnSrboB0_6MMRZWBluAyQ2o7syeaeBd0,2235
1805
+ vellum/workflows/sandbox.py,sha256=xaXjegP1dg1eYEyxjb0iMIBwK4bqzMfi8KPd6lA018k,2854
1806
1806
  vellum/workflows/state/__init__.py,sha256=yUUdR-_Vl7UiixNDYQZ-GEM_kJI9dnOia75TtuNEsnE,60
1807
1807
  vellum/workflows/state/base.py,sha256=m9fCqbZn21GshCVCjJTD1dPZEQjFrsMXqlg7tM9fIwM,24283
1808
- vellum/workflows/state/context.py,sha256=HQbapsGX42rCEn1GuD-jWMpvjrQhosPVJSnashKN2vc,7234
1808
+ vellum/workflows/state/context.py,sha256=i9tQKTB2b2SBpNObtb8skTv63lQcwUDW1ZQ0qDTnGJA,5181
1809
1809
  vellum/workflows/state/delta.py,sha256=7h8wR10lRCm15SykaPj-gSEvvsMjCwYLPsOx3nsvBQg,440
1810
1810
  vellum/workflows/state/encoder.py,sha256=9wj9za3pjLGaKh85IB71YvPDRDtHcw78wR5vyPyKWM8,2708
1811
1811
  vellum/workflows/state/store.py,sha256=uVe-oN73KwGV6M6YLhwZMMUQhzTQomsVfVnb8V91gVo,1147
@@ -1837,13 +1837,13 @@ vellum/workflows/utils/uuids.py,sha256=DFzPv9RCvsKhvdTEIQyfSek2A31D6S_QcmeLPbgrg
1837
1837
  vellum/workflows/utils/vellum_variables.py,sha256=vg7PLTqBoPLWXrcFR2vOfJpKkzvDC85cL2sSUqDWXWU,5503
1838
1838
  vellum/workflows/vellum_client.py,sha256=xkfoucodxNK5JR2-lbRqZx3xzDgExWkP6kySrpi_Ubc,1079
1839
1839
  vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
1840
- vellum/workflows/workflows/base.py,sha256=FTW2y5O8bUgMD1aluavwQ-UYTURRW1DRxDwdynR0OZc,27343
1840
+ vellum/workflows/workflows/base.py,sha256=C17t-YpaBishP5PNThPgmMtYQsint55AcPIweBTVi7I,27354
1841
1841
  vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
1842
1842
  vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1843
1843
  vellum/workflows/workflows/tests/test_base_workflow.py,sha256=ptMntHzVyy8ZuzNgeTuk7hREgKQ5UBdgq8VJFSGaW4Y,20832
1844
1844
  vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
1845
- vellum_ai-1.1.4.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1846
- vellum_ai-1.1.4.dist-info/METADATA,sha256=vtS36kiUPHeBJrpddCNWGFQRpj7hTebtWkd4xCZVdKA,5547
1847
- vellum_ai-1.1.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1848
- vellum_ai-1.1.4.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1849
- vellum_ai-1.1.4.dist-info/RECORD,,
1845
+ vellum_ai-1.2.0.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1846
+ vellum_ai-1.2.0.dist-info/METADATA,sha256=DY_XVUAkrUVX6xUGRfjFW_b-L6NC4xIBs83ertamHTQ,5547
1847
+ vellum_ai-1.2.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1848
+ vellum_ai-1.2.0.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1849
+ vellum_ai-1.2.0.dist-info/RECORD,,
@@ -175,7 +175,7 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
175
175
 
176
176
  adornment: JsonObject = {
177
177
  "id": str(node_id),
178
- "label": node.__qualname__,
178
+ "label": self.label,
179
179
  "base": self.get_base().dict(),
180
180
  "attributes": attributes,
181
181
  }
@@ -205,7 +205,7 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
205
205
 
206
206
  return {
207
207
  "id": str(node_id),
208
- "label": node.__qualname__,
208
+ "label": self.label,
209
209
  "type": "GENERIC",
210
210
  "display_data": self.get_display_data().dict(),
211
211
  "base": self.get_base().dict(),
@@ -417,8 +417,8 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
417
417
  if explicit_value and explicit_value.comment and docstring:
418
418
  comment = (
419
419
  NodeDisplayComment(value=docstring, expanded=explicit_value.comment.expanded)
420
- if explicit_value.comment.expanded
421
- else NodeDisplayComment(value=docstring)
420
+ if explicit_value.comment.expanded is not None
421
+ else NodeDisplayComment(value=docstring, expanded=True)
422
422
  )
423
423
  return NodeDisplayData(
424
424
  position=explicit_value.position,
@@ -432,7 +432,7 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
432
432
 
433
433
  if docstring:
434
434
  return NodeDisplayData(
435
- comment=NodeDisplayComment(value=docstring),
435
+ comment=NodeDisplayComment(value=docstring, expanded=True),
436
436
  )
437
437
 
438
438
  return NodeDisplayData()
@@ -98,5 +98,5 @@ def test_serialize_display_data():
98
98
  # THEN the condition should be serialized correctly
99
99
  assert data["display_data"] == {
100
100
  "position": {"x": 0.0, "y": 0.0},
101
- "comment": {"value": "I hope this works"},
101
+ "comment": {"expanded": True, "value": "I hope this works"},
102
102
  }
@@ -100,6 +100,10 @@ class BaseInlinePromptNodeDisplay(BaseNodeDisplay[_InlinePromptNodeType], Generi
100
100
  "display_data": self.get_display_data().dict(),
101
101
  "base": self.get_base().dict(),
102
102
  "definition": self.get_definition().dict(),
103
+ "trigger": {
104
+ "id": str(self.get_target_handle_id()),
105
+ "merge_behavior": node.Trigger.merge_behavior.value,
106
+ },
103
107
  "outputs": [
104
108
  {"id": str(json_display.id), "name": "json", "type": "JSON", "value": None},
105
109
  {"id": str(output_display.id), "name": "text", "type": "STRING", "value": None},
@@ -39,7 +39,7 @@ class BaseRetryNodeDisplay(BaseAdornmentNodeDisplay[_RetryNodeType], Generic[_Re
39
39
 
40
40
  adornment: JsonObject = {
41
41
  "id": str(node_id),
42
- "label": node.__qualname__,
42
+ "label": self.label,
43
43
  "base": self.get_base().dict(),
44
44
  "attributes": attributes,
45
45
  }
@@ -29,7 +29,7 @@ def test_retry_node_parameters():
29
29
  )
30
30
 
31
31
  retry_adornment = next(
32
- adornment for adornment in serialized_node["adornments"] if adornment["label"] == "RetryNode"
32
+ adornment for adornment in serialized_node["adornments"] if adornment["label"] == "Retry Node"
33
33
  )
34
34
 
35
35
  max_attempts_attribute = next(attr for attr in retry_adornment["attributes"] if attr["name"] == "max_attempts")
@@ -1,6 +1,7 @@
1
1
  from vellum.client.types.prompt_parameters import PromptParameters
2
2
  from vellum.workflows import BaseWorkflow
3
3
  from vellum.workflows.inputs import BaseInputs
4
+ from vellum.workflows.nodes.displayable.code_execution_node.node import CodeExecutionNode
4
5
  from vellum.workflows.nodes.displayable.inline_prompt_node.node import InlinePromptNode
5
6
  from vellum.workflows.nodes.displayable.tool_calling_node.node import ToolCallingNode
6
7
  from vellum.workflows.nodes.displayable.tool_calling_node.state import ToolCallingState
@@ -243,7 +244,7 @@ def test_serialize_tool_router_node():
243
244
  },
244
245
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
245
246
  "id": "690c66e1-1e18-4984-b695-84beb0157541",
246
- "label": "RouterNode",
247
+ "label": "Router Node",
247
248
  "outputs": [],
248
249
  "ports": [
249
250
  {
@@ -332,3 +333,76 @@ def test_serialize_tool_router_node():
332
333
  "trigger": {"id": "73a96f44-c2dd-40cc-96f6-49b9f914b166", "merge_behavior": "AWAIT_ATTRIBUTES"},
333
334
  "type": "GENERIC",
334
335
  }
336
+
337
+
338
+ def test_serialize_node__tool_calling_node__subworkflow_with_parent_input_reference():
339
+ """
340
+ Test that a tool calling node with a subworkflow that references parent inputs serializes correctly
341
+ """
342
+
343
+ # GIVEN a workflow inputs class
344
+ class MyInputs(BaseInputs):
345
+ text: str
346
+ greeting: str
347
+
348
+ # AND a code execution node that references parent inputs
349
+ class CodeExecution(CodeExecutionNode[BaseState, str]):
350
+ code = ""
351
+ code_inputs = {
352
+ "text": MyInputs.text,
353
+ }
354
+ runtime = "PYTHON_3_11_6"
355
+ packages = []
356
+
357
+ # AND a subworkflow that uses the code execution node
358
+ class FunctionSubworkflow(BaseWorkflow):
359
+ graph = CodeExecution
360
+
361
+ class Outputs(BaseWorkflow.Outputs):
362
+ output = CodeExecution.Outputs.result
363
+
364
+ # AND a tool calling node that uses the subworkflow
365
+ class MyToolCallingNode(ToolCallingNode):
366
+ ml_model = "gpt-4.1"
367
+ prompt_inputs = {
368
+ "text": MyInputs.text,
369
+ }
370
+ blocks = []
371
+ parameters = PromptParameters()
372
+ functions = [FunctionSubworkflow]
373
+
374
+ # AND a workflow with the tool calling node
375
+ class Workflow(BaseWorkflow[MyInputs, BaseState]):
376
+ graph = MyToolCallingNode
377
+
378
+ # WHEN the workflow is serialized
379
+ workflow_display = get_workflow_display(workflow_class=Workflow)
380
+ serialized_workflow: dict = workflow_display.serialize()
381
+
382
+ # THEN the node should properly serialize the functions with parent input references
383
+ my_tool_calling_node = next(
384
+ node
385
+ for node in serialized_workflow["workflow_raw_data"]["nodes"]
386
+ if node["id"] == str(MyToolCallingNode.__id__)
387
+ )
388
+
389
+ functions_attribute = next(
390
+ attribute for attribute in my_tool_calling_node["attributes"] if attribute["name"] == "functions"
391
+ )
392
+
393
+ data = functions_attribute["value"]["value"]["value"][0]
394
+ nodes = data["exec_config"]["workflow_raw_data"]["nodes"]
395
+ code_exec_node = next((node for node in nodes if node["type"] == "CODE_EXECUTION"), None)
396
+
397
+ assert code_exec_node is not None
398
+ text_input = next((input for input in code_exec_node["inputs"] if input["key"] == "text"), None)
399
+ assert text_input == {
400
+ "id": "da92a1c4-d37c-4008-a1ab-c0bcc0cd20d0",
401
+ "key": "text",
402
+ "value": {
403
+ "rules": [
404
+ {"type": "INPUT_VARIABLE", "data": {"input_variable_id": "6f0c1889-3f08-4c5c-bb24-f7b94169105c"}}
405
+ ],
406
+ "combinator": "OR",
407
+ },
408
+ }
@@ -43,7 +43,7 @@ class BaseTryNodeDisplay(BaseAdornmentNodeDisplay[_TryNodeType], Generic[_TryNod
43
43
 
44
44
  adornment: JsonObject = {
45
45
  "id": str(node_id),
46
- "label": node.__qualname__,
46
+ "label": self.label,
47
47
  "base": self.get_base().dict(),
48
48
  "attributes": attributes,
49
49
  }
@@ -47,7 +47,7 @@ def test_serialize_node__retry(serialize_node):
47
47
  assert not DeepDiff(
48
48
  {
49
49
  "id": "188b50aa-e518-4b7b-a5e0-e2585fb1d7b5",
50
- "label": "test_serialize_node__retry.<locals>.InnerRetryGenericNode",
50
+ "label": "Inner Retry Generic Node",
51
51
  "type": "GENERIC",
52
52
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
53
53
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -68,7 +68,7 @@ def test_serialize_node__retry(serialize_node):
68
68
  "adornments": [
69
69
  {
70
70
  "id": "5be7d260-74f7-4734-b31b-a46a94539586",
71
- "label": "RetryNode",
71
+ "label": "Retry Node",
72
72
  "base": {
73
73
  "name": "RetryNode",
74
74
  "module": ["vellum", "workflows", "nodes", "core", "retry_node", "node"],
@@ -154,7 +154,7 @@ def test_serialize_node__try(serialize_node):
154
154
  assert not DeepDiff(
155
155
  {
156
156
  "id": str(InnerTryGenericNode.__wrapped_node__.__id__),
157
- "label": "test_serialize_node__try.<locals>.InnerTryGenericNode",
157
+ "label": "Inner Try Generic Node",
158
158
  "type": "GENERIC",
159
159
  "display_data": {"position": {"x": 0.0, "y": 0.0}},
160
160
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -175,7 +175,7 @@ def test_serialize_node__try(serialize_node):
175
175
  "adornments": [
176
176
  {
177
177
  "id": "3344083c-a32c-4a32-920b-0fb5093448fa",
178
- "label": "TryNode",
178
+ "label": "Try Node",
179
179
  "base": {
180
180
  "name": "TryNode",
181
181
  "module": ["vellum", "workflows", "nodes", "core", "try_node", "node"],
@@ -248,7 +248,7 @@ def test_serialize_node__stacked():
248
248
  assert not DeepDiff(
249
249
  {
250
250
  "id": "074833b0-e142-4bbc-8dec-209a35e178a3",
251
- "label": "test_serialize_node__stacked.<locals>.InnerStackedGenericNode",
251
+ "label": "Inner Stacked Generic Node",
252
252
  "type": "GENERIC",
253
253
  "display_data": {"position": {"x": 200.0, "y": -50.0}},
254
254
  "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
@@ -272,7 +272,7 @@ def test_serialize_node__stacked():
272
272
  "adornments": [
273
273
  {
274
274
  "id": "3344083c-a32c-4a32-920b-0fb5093448fa",
275
- "label": "TryNode",
275
+ "label": "Try Node",
276
276
  "base": {
277
277
  "name": "TryNode",
278
278
  "module": ["vellum", "workflows", "nodes", "core", "try_node", "node"],
@@ -287,7 +287,7 @@ def test_serialize_node__stacked():
287
287
  },
288
288
  {
289
289
  "id": "5be7d260-74f7-4734-b31b-a46a94539586",
290
- "label": "RetryNode",
290
+ "label": "Retry Node",
291
291
  "base": {
292
292
  "name": "RetryNode",
293
293
  "module": ["vellum", "workflows", "nodes", "core", "retry_node", "node"],
@@ -351,5 +351,5 @@ def test_serialize_node__adornment_order_matches_decorator_order():
351
351
 
352
352
  adornments = cast(List[Dict[str, Any]], my_node["adornments"])
353
353
  assert len(adornments) == 2
354
- assert adornments[0]["label"] == "TryNode"
355
- assert adornments[1]["label"] == "RetryNode"
354
+ assert adornments[0]["label"] == "Try Node"
355
+ assert adornments[1]["label"] == "Retry Node"