vellum-ai 1.7.6__py3-none-any.whl → 1.7.7__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.
- vellum/client/core/client_wrapper.py +2 -2
- vellum/workflows/nodes/bases/base_adornment_node.py +53 -1
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +3 -1
- vellum/workflows/runner/runner.py +17 -15
- {vellum_ai-1.7.6.dist-info → vellum_ai-1.7.7.dist-info}/METADATA +1 -1
- {vellum_ai-1.7.6.dist-info → vellum_ai-1.7.7.dist-info}/RECORD +12 -12
- vellum_ee/workflows/display/nodes/base_node_display.py +1 -1
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +16 -0
- vellum_ee/workflows/display/utils/expressions.py +11 -11
- {vellum_ai-1.7.6.dist-info → vellum_ai-1.7.7.dist-info}/LICENSE +0 -0
- {vellum_ai-1.7.6.dist-info → vellum_ai-1.7.7.dist-info}/WHEEL +0 -0
- {vellum_ai-1.7.6.dist-info → vellum_ai-1.7.7.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.7.
|
30
|
+
"User-Agent": "vellum-ai/1.7.7",
|
31
31
|
"X-Fern-Language": "Python",
|
32
32
|
"X-Fern-SDK-Name": "vellum-ai",
|
33
|
-
"X-Fern-SDK-Version": "1.7.
|
33
|
+
"X-Fern-SDK-Version": "1.7.7",
|
34
34
|
**(self.get_custom_headers() or {}),
|
35
35
|
}
|
36
36
|
if self._api_version is not None:
|
@@ -1,10 +1,12 @@
|
|
1
1
|
from abc import ABC
|
2
|
-
from
|
2
|
+
from uuid import UUID
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, Generic, Optional, Set, Tuple, Type
|
3
4
|
|
4
5
|
from vellum.workflows.inputs.base import BaseInputs
|
5
6
|
from vellum.workflows.nodes.bases.base import BaseNode, BaseNodeMeta
|
6
7
|
from vellum.workflows.outputs.base import BaseOutputs
|
7
8
|
from vellum.workflows.references.output import OutputReference
|
9
|
+
from vellum.workflows.types.core import MergeBehavior
|
8
10
|
from vellum.workflows.types.generics import StateType
|
9
11
|
|
10
12
|
if TYPE_CHECKING:
|
@@ -79,6 +81,56 @@ class BaseAdornmentNode(
|
|
79
81
|
__wrapped_node__: Optional[Type["BaseNode"]] = None
|
80
82
|
subworkflow: Type["BaseWorkflow"]
|
81
83
|
|
84
|
+
class Trigger(BaseNode.Trigger):
|
85
|
+
"""
|
86
|
+
Trigger class for adornment nodes that delegates to the wrapped node's Trigger
|
87
|
+
for proper merge behavior handling.
|
88
|
+
"""
|
89
|
+
|
90
|
+
@classmethod
|
91
|
+
def should_initiate(
|
92
|
+
cls,
|
93
|
+
state: StateType,
|
94
|
+
dependencies: Set["Type[BaseNode]"],
|
95
|
+
node_span_id: UUID,
|
96
|
+
) -> bool:
|
97
|
+
"""
|
98
|
+
Delegates to the wrapped node's Trigger.should_initiate method to ensure
|
99
|
+
proper merge behavior (like AWAIT_ALL) is respected for initiation logic.
|
100
|
+
"""
|
101
|
+
# Get the wrapped node's Trigger class
|
102
|
+
wrapped_node = cls.node_class.__wrapped_node__
|
103
|
+
if wrapped_node is not None:
|
104
|
+
wrapped_trigger = wrapped_node.Trigger
|
105
|
+
# Only delegate if the wrapped node has a specific merge behavior
|
106
|
+
# that differs from the default AWAIT_ATTRIBUTES
|
107
|
+
if (
|
108
|
+
hasattr(wrapped_trigger, "merge_behavior")
|
109
|
+
and wrapped_trigger.merge_behavior != MergeBehavior.AWAIT_ATTRIBUTES
|
110
|
+
):
|
111
|
+
return wrapped_trigger.should_initiate(state, dependencies, node_span_id)
|
112
|
+
|
113
|
+
# Fallback to the base implementation if no wrapped node
|
114
|
+
return super().should_initiate(state, dependencies, node_span_id)
|
115
|
+
|
116
|
+
@classmethod
|
117
|
+
def _queue_node_execution(
|
118
|
+
cls, state: StateType, dependencies: set[Type[BaseNode]], invoked_by: Optional[UUID] = None
|
119
|
+
) -> UUID:
|
120
|
+
"""
|
121
|
+
Delegates to the wrapped node's Trigger._queue_node_execution method to ensure
|
122
|
+
proper merge behavior (like AWAIT_ALL) is respected for dependency tracking.
|
123
|
+
"""
|
124
|
+
# Get the wrapped node's Trigger class
|
125
|
+
wrapped_node = cls.node_class.__wrapped_node__
|
126
|
+
if wrapped_node is not None:
|
127
|
+
wrapped_trigger = wrapped_node.Trigger
|
128
|
+
# Delegate to the wrapped node's trigger logic for queuing
|
129
|
+
return wrapped_trigger._queue_node_execution(state, dependencies, invoked_by)
|
130
|
+
|
131
|
+
# Fallback to the base implementation if no wrapped node
|
132
|
+
return super()._queue_node_execution(state, dependencies, invoked_by)
|
133
|
+
|
82
134
|
@classmethod
|
83
135
|
def __annotate_outputs_class__(cls, outputs_class: Type[BaseOutputs], reference: OutputReference) -> None:
|
84
136
|
# Subclasses of BaseAdornableNode can override this method to provider their own
|
@@ -7,6 +7,7 @@ from vellum import (
|
|
7
7
|
AdHocExpandMeta,
|
8
8
|
ChatMessage,
|
9
9
|
FunctionDefinition,
|
10
|
+
InitiatedAdHocExecutePromptEvent,
|
10
11
|
PromptBlock,
|
11
12
|
PromptOutput,
|
12
13
|
PromptParameters,
|
@@ -185,7 +186,8 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
|
|
185
186
|
expand_meta=self.expand_meta,
|
186
187
|
request_options=request_options,
|
187
188
|
)
|
188
|
-
|
189
|
+
initiated_event = InitiatedAdHocExecutePromptEvent(execution_id=response.execution_id)
|
190
|
+
return iter([initiated_event, response])
|
189
191
|
else:
|
190
192
|
return self._context.vellum_client.ad_hoc.adhoc_execute_prompt_stream(
|
191
193
|
ml_model=self.ml_model,
|
@@ -724,22 +724,24 @@ class WorkflowRunner(Generic[StateType]):
|
|
724
724
|
parent_context: The parent context for the cancellation events
|
725
725
|
"""
|
726
726
|
captured_stacktrace = "".join(traceback.format_stack())
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
727
|
+
active_span_ids = list(self._active_nodes_by_execution_id.keys())
|
728
|
+
for span_id in active_span_ids:
|
729
|
+
active_node = self._active_nodes_by_execution_id.pop(span_id, None)
|
730
|
+
if active_node is not None:
|
731
|
+
rejection_event = NodeExecutionRejectedEvent(
|
732
|
+
trace_id=self._execution_context.trace_id,
|
733
|
+
span_id=span_id,
|
734
|
+
body=NodeExecutionRejectedBody(
|
735
|
+
node_definition=active_node.node.__class__,
|
736
|
+
error=WorkflowError(
|
737
|
+
code=WorkflowErrorCode.NODE_CANCELLED,
|
738
|
+
message=error_message,
|
739
|
+
),
|
740
|
+
stacktrace=captured_stacktrace,
|
736
741
|
),
|
737
|
-
|
738
|
-
)
|
739
|
-
|
740
|
-
)
|
741
|
-
self._workflow_event_outer_queue.put(rejection_event)
|
742
|
-
self._active_nodes_by_execution_id.pop(span_id)
|
742
|
+
parent=parent_context,
|
743
|
+
)
|
744
|
+
self._workflow_event_outer_queue.put(rejection_event)
|
743
745
|
|
744
746
|
def _initiate_workflow_event(self) -> WorkflowExecutionInitiatedEvent:
|
745
747
|
links: Optional[List[SpanLink]] = None
|
@@ -32,7 +32,7 @@ vellum_ee/workflows/display/editor/__init__.py,sha256=MSAgY91xCEg2neH5d8jXx5wRdR
|
|
32
32
|
vellum_ee/workflows/display/editor/types.py,sha256=rmaNXkNZUNRgK-mJJ_g1-Fm3OGxoQfqEB7zn-zzgJtc,664
|
33
33
|
vellum_ee/workflows/display/exceptions.py,sha256=_FDhK-lfuBPHY2GSywp70ewM0k55Ji5Bp-wZlEZenz4,112
|
34
34
|
vellum_ee/workflows/display/nodes/__init__.py,sha256=jI1aPBQf8DkmrYoZ4O-wR1duqZByOf5mDFmo_wFJPE4,307
|
35
|
-
vellum_ee/workflows/display/nodes/base_node_display.py,sha256=
|
35
|
+
vellum_ee/workflows/display/nodes/base_node_display.py,sha256=ceKQdHZmDSOY5-M2DtJnuLbdkuFujCChFtRABDoV1jo,19497
|
36
36
|
vellum_ee/workflows/display/nodes/get_node_display_class.py,sha256=jI_kUi9LnNLDpY63QtlC4TfN8P571VN4LpzH0I1ZtLk,1149
|
37
37
|
vellum_ee/workflows/display/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
38
|
vellum_ee/workflows/display/nodes/tests/test_base_node_display.py,sha256=JLa9nlG38dLfCo1Y8ISsJ21hrfDyy4-ae3pZ9H01yFs,5578
|
@@ -80,7 +80,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/__init__.py,sha256=47DE
|
|
80
80
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
81
81
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py,sha256=Y-ajeT65b5varmrZCw6L3hir4hJCFq-eO0jZfRcrs7g,1886
|
82
82
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py,sha256=wdVaFvxicj48Kj-6VUlu61KR0oSArLTjownRi2p0NWQ,14941
|
83
|
-
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py,sha256=
|
83
|
+
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py,sha256=rDh6PxhdoVDNuKdUrtZpoMtX8T92ZUMonkVxDjeEE4g,25507
|
84
84
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py,sha256=SwXRzjdoEZLvkzaRMvRV8_UqbBm0EB_UtAHD_zXKZBY,6303
|
85
85
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py,sha256=jubGYgLJImOqILd5LjnYJ4B1UMIrToDrQbPZOvaQCX4,40035
|
86
86
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py,sha256=FLvcD8eoABHUPv08oSpIp_P-65sw2gl4whMXEJJj4f8,6785
|
@@ -119,7 +119,7 @@ vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
|
|
119
119
|
vellum_ee/workflows/display/utils/auto_layout.py,sha256=f4GiLn_LazweupfqTpubcdtdfE_vrOcmZudSsnYIY9E,3906
|
120
120
|
vellum_ee/workflows/display/utils/events.py,sha256=DE33uoKW78BZtITJ6L22dMZN3KR1BuZBVC98C_gIyzU,1943
|
121
121
|
vellum_ee/workflows/display/utils/exceptions.py,sha256=E8Lvo7LY1BoZ54M_NR_opDjJsAAiCUfow1HgoHcTHmg,989
|
122
|
-
vellum_ee/workflows/display/utils/expressions.py,sha256=
|
122
|
+
vellum_ee/workflows/display/utils/expressions.py,sha256=IIieWILv2zGLYTRgeDwgjhtga1ttV-ss2remJ1HBVXA,20688
|
123
123
|
vellum_ee/workflows/display/utils/registry.py,sha256=1qXiBTdsnro6FeCX0FGBEK7CIf6wa--Jt50iZ_nEp_M,3460
|
124
124
|
vellum_ee/workflows/display/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
125
125
|
vellum_ee/workflows/display/utils/tests/test_auto_layout.py,sha256=vfXI769418s9vda5Gb5NFBH747WMOwSgHRXeLCTLVm8,2356
|
@@ -161,7 +161,7 @@ vellum/client/README.md,sha256=flqu57ubZNTfpq60CdLtJC9gp4WEkyjb_n_eZ4OYf9w,6497
|
|
161
161
|
vellum/client/__init__.py,sha256=rMnKRqL5-356SBc-rfm56MkO87PuAi2mtcfBszcJU1M,74316
|
162
162
|
vellum/client/core/__init__.py,sha256=lTcqUPXcx4112yLDd70RAPeqq6tu3eFMe1pKOqkW9JQ,1562
|
163
163
|
vellum/client/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
|
164
|
-
vellum/client/core/client_wrapper.py,sha256=
|
164
|
+
vellum/client/core/client_wrapper.py,sha256=A3sL2WdcS11xGFV5Yq5h9yzf-96DpP7AL8dayvAKlUk,2840
|
165
165
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
166
166
|
vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
|
167
167
|
vellum/client/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
|
@@ -1886,7 +1886,7 @@ vellum/workflows/logging.py,sha256=_a217XogktV4Ncz6xKFz7WfYmZAzkfVRVuC0rWob8ls,4
|
|
1886
1886
|
vellum/workflows/nodes/__init__.py,sha256=zymtc3_iW2rFmMR-sayTLuN6ZsAw8VnJweWPsjQk2-Q,1197
|
1887
1887
|
vellum/workflows/nodes/bases/__init__.py,sha256=cniHuz_RXdJ4TQgD8CBzoiKDiPxg62ErdVpCbWICX64,58
|
1888
1888
|
vellum/workflows/nodes/bases/base.py,sha256=u7NmYWhQZm91KZV53PGD-gpZvcWAItOme95TjZkHwDI,22094
|
1889
|
-
vellum/workflows/nodes/bases/base_adornment_node.py,sha256=
|
1889
|
+
vellum/workflows/nodes/bases/base_adornment_node.py,sha256=TgL-tfX84GyTb7ONQ2z7OJDkx57kW3qbQNDuiw-Zrqo,5814
|
1890
1890
|
vellum/workflows/nodes/bases/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1891
1891
|
vellum/workflows/nodes/bases/tests/test_base_adornment_node.py,sha256=fXZI9KqpS4XMBrBnIEkK3foHaBVvyHwYcQWWDKay7ic,1148
|
1892
1892
|
vellum/workflows/nodes/bases/tests/test_base_node.py,sha256=igJrcSxSZADk5tLpssAt0uAXe9oJoLbilzueJJvA5p4,10942
|
@@ -1925,7 +1925,7 @@ vellum/workflows/nodes/displayable/bases/api_node/tests/test_node.py,sha256=5C59
|
|
1925
1925
|
vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py,sha256=Org3xTvgp1pA0uUXFfnJr29D3HzCey2lEdYF4zbIUgo,70
|
1926
1926
|
vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=w02vgydiwNoKru324QLSkH3BiGUvHTgKbf05BEx945s,4657
|
1927
1927
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py,sha256=Hl35IAoepRpE-j4cALaXVJIYTYOF3qszyVbxTj4kS1s,82
|
1928
|
-
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=
|
1928
|
+
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=ITxAa1HWF6OPdcKg0DdTK7YP94ezzzWVyZzCRMiybIg,18638
|
1929
1929
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1930
1930
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py,sha256=xc53wGwVqxBnN7eoyWkJ-RJ-FeUpHKekkKjViASHAFg,27495
|
1931
1931
|
vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py,sha256=H9mM75EQpP6PUvsXCTbwjw4CqMMLf36m1G2XqiPEvH4,12139
|
@@ -2025,7 +2025,7 @@ vellum/workflows/resolvers/resolver.py,sha256=3uEYscB_2PHTazc0Y9SzOe_yiQZhVLfey1
|
|
2025
2025
|
vellum/workflows/resolvers/tests/test_resolver.py,sha256=PnUGzsulo1It_LjjhHsRNiILvvl5G_IaK8ZX56zKC28,6204
|
2026
2026
|
vellum/workflows/resolvers/types.py,sha256=Hndhlk69g6EKLh_LYg5ILepW5U_h_BYNllfzhS9k8p4,237
|
2027
2027
|
vellum/workflows/runner/__init__.py,sha256=i1iG5sAhtpdsrlvwgH6B-m49JsINkiWyPWs8vyT-bqM,72
|
2028
|
-
vellum/workflows/runner/runner.py,sha256=
|
2028
|
+
vellum/workflows/runner/runner.py,sha256=IYjeFx6_jescg8tEW-et5k96X9EsB6PDw4Kw4Qvy-Xo,45599
|
2029
2029
|
vellum/workflows/sandbox.py,sha256=mezSZmilR_fwR8164n8CEfzlMeQ55IqfapHp4ftImvQ,3212
|
2030
2030
|
vellum/workflows/state/__init__.py,sha256=yUUdR-_Vl7UiixNDYQZ-GEM_kJI9dnOia75TtuNEsnE,60
|
2031
2031
|
vellum/workflows/state/base.py,sha256=A8s0PC8UvFjPpkHDY6u-yIeb2KHjoAmu-GW-GYrDl0E,24654
|
@@ -2075,8 +2075,8 @@ vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnad
|
|
2075
2075
|
vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2076
2076
|
vellum/workflows/workflows/tests/test_base_workflow.py,sha256=Boa-_m9ii2Qsa1RvVM-VYniF7zCpzGgEGy-OnPZkrHg,23941
|
2077
2077
|
vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
|
2078
|
-
vellum_ai-1.7.
|
2079
|
-
vellum_ai-1.7.
|
2080
|
-
vellum_ai-1.7.
|
2081
|
-
vellum_ai-1.7.
|
2082
|
-
vellum_ai-1.7.
|
2078
|
+
vellum_ai-1.7.7.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
2079
|
+
vellum_ai-1.7.7.dist-info/METADATA,sha256=AUowwbBfQrczLwFHQeRVeZoiVw6lIuKUlK52uh9Qb6o,5547
|
2080
|
+
vellum_ai-1.7.7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
2081
|
+
vellum_ai-1.7.7.dist-info/entry_points.txt,sha256=xVavzAKN4iF_NbmhWOlOkHluka0YLkbN_pFQ9pW3gLI,117
|
2082
|
+
vellum_ai-1.7.7.dist-info/RECORD,,
|
@@ -188,7 +188,7 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
|
|
188
188
|
type = primitive_type_to_vellum_variable_type(output)
|
189
189
|
value = (
|
190
190
|
serialize_value(node_id, display_context, output.instance)
|
191
|
-
if output.instance is not None and output.instance
|
191
|
+
if output.instance is not None and output.instance is not undefined
|
192
192
|
else None
|
193
193
|
)
|
194
194
|
|
@@ -688,3 +688,19 @@ def test_serialize_node__comment_expanded_preserved_when_explicitly_set(serializ
|
|
688
688
|
assert "comment" in display_data
|
689
689
|
assert display_data["comment"]["value"] == "This is a test comment."
|
690
690
|
assert display_data["comment"]["expanded"] is False
|
691
|
+
|
692
|
+
|
693
|
+
def test_serialize_node__attribute_with_type_annotation_no_default(serialize_node):
|
694
|
+
"""
|
695
|
+
Tests that attributes with type annotations but no default values serialize as None.
|
696
|
+
"""
|
697
|
+
|
698
|
+
# GIVEN a node with typed attributes but no default values
|
699
|
+
class NodeWithTypedAttributesNoDefault(BaseNode):
|
700
|
+
attr: str
|
701
|
+
|
702
|
+
# WHEN the node is serialized
|
703
|
+
serialized_node = serialize_node(NodeWithTypedAttributesNoDefault)
|
704
|
+
|
705
|
+
# THEN the attribute should serialize as None
|
706
|
+
assert serialized_node["attributes"][0]["value"] is None
|
@@ -3,7 +3,7 @@ import inspect
|
|
3
3
|
from io import StringIO
|
4
4
|
import sys
|
5
5
|
from uuid import UUID
|
6
|
-
from typing import TYPE_CHECKING, Any, Dict, List, cast
|
6
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast
|
7
7
|
|
8
8
|
from pydantic import BaseModel
|
9
9
|
|
@@ -248,13 +248,11 @@ def serialize_key(key: Any) -> str:
|
|
248
248
|
return str(key)
|
249
249
|
|
250
250
|
|
251
|
-
|
252
|
-
_UNDEFINED_SENTINEL: JsonObject = {"__undefined__": True}
|
253
|
-
|
254
|
-
|
255
|
-
def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContext", value: Any) -> JsonObject:
|
251
|
+
def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContext", value: Any) -> Optional[JsonObject]:
|
256
252
|
"""
|
257
|
-
Serialize a value to a JSON object.
|
253
|
+
Serialize a value to a JSON object. Returns `None` if the value resolves to `undefined`.
|
254
|
+
This is safe because all valid values are a JSON object, including the `None` constant:
|
255
|
+
> `{"type": "CONSTANT_VALUE", "value": {"type": "JSON", "value": None}}`
|
258
256
|
|
259
257
|
Args:
|
260
258
|
executable_id: node id or workflow id
|
@@ -265,7 +263,7 @@ def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContex
|
|
265
263
|
serialized value
|
266
264
|
"""
|
267
265
|
if value is undefined:
|
268
|
-
return
|
266
|
+
return None
|
269
267
|
|
270
268
|
if isinstance(value, ConstantValueReference):
|
271
269
|
return serialize_value(executable_id, display_context, value._value)
|
@@ -353,7 +351,7 @@ def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContex
|
|
353
351
|
serialized_items = []
|
354
352
|
for item in value:
|
355
353
|
serialized_item = serialize_value(executable_id, display_context, item)
|
356
|
-
if serialized_item
|
354
|
+
if serialized_item is not None:
|
357
355
|
serialized_items.append(serialized_item)
|
358
356
|
|
359
357
|
if all(isinstance(item, dict) and item["type"] == "CONSTANT_VALUE" for item in serialized_items):
|
@@ -389,7 +387,7 @@ def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContex
|
|
389
387
|
serialized_entries: List[Dict[str, Any]] = []
|
390
388
|
for key, val in value.items():
|
391
389
|
serialized_val = serialize_value(executable_id, display_context, val)
|
392
|
-
if serialized_val
|
390
|
+
if serialized_val is not None:
|
393
391
|
serialized_entries.append(
|
394
392
|
{
|
395
393
|
"id": str(uuid4_from_hash(f"{executable_id}|{key}")),
|
@@ -455,7 +453,9 @@ def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContex
|
|
455
453
|
if inputs:
|
456
454
|
serialized_inputs = {}
|
457
455
|
for param_name, input_ref in inputs.items():
|
458
|
-
|
456
|
+
serialized_input = serialize_value(executable_id, display_context, input_ref)
|
457
|
+
if serialized_input is not None:
|
458
|
+
serialized_inputs[param_name] = serialized_input
|
459
459
|
|
460
460
|
model_data = function_definition.model_dump()
|
461
461
|
model_data["inputs"] = serialized_inputs
|
File without changes
|
File without changes
|
File without changes
|