vellum-ai 1.7.8__py3-none-any.whl → 1.7.9__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/errors/types.py +3 -0
- vellum/workflows/graph/graph.py +4 -1
- vellum/workflows/runner/runner.py +17 -5
- vellum/workflows/utils/functions.py +1 -1
- vellum/workflows/workflows/base.py +2 -2
- {vellum_ai-1.7.8.dist-info → vellum_ai-1.7.9.dist-info}/METADATA +1 -1
- {vellum_ai-1.7.8.dist-info → vellum_ai-1.7.9.dist-info}/RECORD +32 -32
- vellum_ee/assets/node-definitions.json +91 -65
- vellum_ee/workflows/display/nodes/base_node_display.py +46 -26
- vellum_ee/workflows/display/nodes/vellum/code_execution_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/conditional_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/error_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/final_output_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/guardrail_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/map_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/merge_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/note_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/search_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/templating_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/tests/test_api_node.py +34 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +8 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_manual_trigger_serialization.py +33 -70
- vellum_ee/workflows/display/utils/expressions.py +12 -0
- vellum_ee/workflows/display/workflows/base_workflow_display.py +1 -1
- {vellum_ai-1.7.8.dist-info → vellum_ai-1.7.9.dist-info}/LICENSE +0 -0
- {vellum_ai-1.7.8.dist-info → vellum_ai-1.7.9.dist-info}/WHEEL +0 -0
- {vellum_ai-1.7.8.dist-info → vellum_ai-1.7.9.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.9",
|
|
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.9",
|
|
34
34
|
**(self.get_custom_headers() or {}),
|
|
35
35
|
}
|
|
36
36
|
if self._api_version is not None:
|
vellum/workflows/errors/types.py
CHANGED
|
@@ -23,6 +23,7 @@ class WorkflowErrorCode(Enum):
|
|
|
23
23
|
PROVIDER_CREDENTIALS_UNAVAILABLE = "PROVIDER_CREDENTIALS_UNAVAILABLE"
|
|
24
24
|
INTEGRATION_CREDENTIALS_UNAVAILABLE = "INTEGRATION_CREDENTIALS_UNAVAILABLE"
|
|
25
25
|
PROVIDER_ERROR = "PROVIDER_ERROR"
|
|
26
|
+
PROVIDER_QUOTA_EXCEEDED = "PROVIDER_QUOTA_EXCEEDED"
|
|
26
27
|
USER_DEFINED_ERROR = "USER_DEFINED_ERROR"
|
|
27
28
|
WORKFLOW_CANCELLED = "WORKFLOW_CANCELLED"
|
|
28
29
|
NODE_CANCELLED = "NODE_CANCELLED"
|
|
@@ -44,6 +45,7 @@ _VELLUM_ERROR_CODE_TO_WORKFLOW_ERROR_CODE: Dict[VellumErrorCodeEnum, WorkflowErr
|
|
|
44
45
|
"INVALID_INPUTS": WorkflowErrorCode.INVALID_INPUTS,
|
|
45
46
|
"PROVIDER_ERROR": WorkflowErrorCode.PROVIDER_ERROR,
|
|
46
47
|
"PROVIDER_CREDENTIALS_UNAVAILABLE": WorkflowErrorCode.PROVIDER_CREDENTIALS_UNAVAILABLE,
|
|
48
|
+
"PROVIDER_QUOTA_EXCEEDED": WorkflowErrorCode.PROVIDER_QUOTA_EXCEEDED,
|
|
47
49
|
"INTEGRATION_CREDENTIALS_UNAVAILABLE": WorkflowErrorCode.INTEGRATION_CREDENTIALS_UNAVAILABLE,
|
|
48
50
|
"REQUEST_TIMEOUT": WorkflowErrorCode.PROVIDER_ERROR,
|
|
49
51
|
"INTERNAL_SERVER_ERROR": WorkflowErrorCode.INTERNAL_ERROR,
|
|
@@ -99,6 +101,7 @@ _WORKFLOW_ERROR_CODE_TO_VELLUM_ERROR_CODE: Dict[WorkflowErrorCode, VellumErrorCo
|
|
|
99
101
|
WorkflowErrorCode.NODE_EXECUTION: "USER_DEFINED_ERROR",
|
|
100
102
|
WorkflowErrorCode.PROVIDER_ERROR: "PROVIDER_ERROR",
|
|
101
103
|
WorkflowErrorCode.PROVIDER_CREDENTIALS_UNAVAILABLE: "PROVIDER_CREDENTIALS_UNAVAILABLE",
|
|
104
|
+
WorkflowErrorCode.PROVIDER_QUOTA_EXCEEDED: "PROVIDER_QUOTA_EXCEEDED",
|
|
102
105
|
WorkflowErrorCode.INTEGRATION_CREDENTIALS_UNAVAILABLE: "INTEGRATION_CREDENTIALS_UNAVAILABLE",
|
|
103
106
|
WorkflowErrorCode.USER_DEFINED_ERROR: "USER_DEFINED_ERROR",
|
|
104
107
|
WorkflowErrorCode.WORKFLOW_CANCELLED: "REQUEST_TIMEOUT",
|
vellum/workflows/graph/graph.py
CHANGED
|
@@ -175,7 +175,10 @@ class Graph:
|
|
|
175
175
|
)
|
|
176
176
|
|
|
177
177
|
if not self._edges and not self._entrypoints:
|
|
178
|
-
raise ValueError(
|
|
178
|
+
raise ValueError(
|
|
179
|
+
"Cannot create edges from nodes with empty Ports classes (like TERMINAL/FinalOutputNode). "
|
|
180
|
+
"TERMINAL nodes are designed to be workflow outputs and cannot connect to other nodes."
|
|
181
|
+
)
|
|
179
182
|
|
|
180
183
|
if self._terminals and all(isinstance(terminal, NoPortsNode) for terminal in self._terminals):
|
|
181
184
|
terminal_names = [terminal.node_class.__name__ for terminal in self._terminals]
|
|
@@ -82,7 +82,7 @@ if TYPE_CHECKING:
|
|
|
82
82
|
|
|
83
83
|
logger = logging.getLogger(__name__)
|
|
84
84
|
|
|
85
|
-
RunFromNodeArg = Sequence[Type[BaseNode]]
|
|
85
|
+
RunFromNodeArg = Sequence[Union[Type[BaseNode], UUID]]
|
|
86
86
|
ExternalInputsArg = Dict[ExternalInputReference, Any]
|
|
87
87
|
BackgroundThreadItem = Union[BaseState, WorkflowEvent, None]
|
|
88
88
|
|
|
@@ -117,19 +117,31 @@ class WorkflowRunner(Generic[StateType]):
|
|
|
117
117
|
self._should_emit_initial_state = True
|
|
118
118
|
self._span_link_info: Optional[Tuple[str, str, str, str]] = None
|
|
119
119
|
if entrypoint_nodes:
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
nodes_by_id = {node.__id__: node for node in self.workflow.get_all_nodes()}
|
|
121
|
+
|
|
122
|
+
resolved_nodes = []
|
|
123
|
+
for item in entrypoint_nodes:
|
|
124
|
+
if isinstance(item, UUID):
|
|
125
|
+
matching_node = nodes_by_id.get(item)
|
|
126
|
+
if matching_node is None:
|
|
127
|
+
raise ValueError(f"No node found with UUID {item}")
|
|
128
|
+
resolved_nodes.append(matching_node)
|
|
129
|
+
else:
|
|
130
|
+
resolved_nodes.append(item)
|
|
131
|
+
|
|
132
|
+
if len(list(resolved_nodes)) > 1:
|
|
133
|
+
raise WorkflowInitializationException("Cannot resume from multiple nodes")
|
|
122
134
|
|
|
123
135
|
# TODO: Support resuming from multiple nodes
|
|
124
136
|
# https://app.shortcut.com/vellum/story/4408
|
|
125
|
-
node = next(iter(
|
|
137
|
+
node = next(iter(resolved_nodes))
|
|
126
138
|
if state:
|
|
127
139
|
self._initial_state = deepcopy(state)
|
|
128
140
|
self._initial_state.meta.span_id = uuid4()
|
|
129
141
|
self._initial_state.meta.workflow_definition = self.workflow.__class__
|
|
130
142
|
else:
|
|
131
143
|
self._initial_state = self.workflow.get_state_at_node(node)
|
|
132
|
-
self._entrypoints =
|
|
144
|
+
self._entrypoints = resolved_nodes
|
|
133
145
|
elif external_inputs:
|
|
134
146
|
self._initial_state = self.workflow.get_most_recent_state()
|
|
135
147
|
for descriptor, value in external_inputs.items():
|
|
@@ -283,7 +283,7 @@ def compile_mcp_tool_definition(server_def: MCPServer) -> List[MCPToolDefinition
|
|
|
283
283
|
We do tool discovery on the MCP server to get the tool definitions.
|
|
284
284
|
|
|
285
285
|
Args:
|
|
286
|
-
|
|
286
|
+
server_def: The basic MCPToolDefinition to enhance
|
|
287
287
|
|
|
288
288
|
Returns:
|
|
289
289
|
MCPToolDefinition with detailed parameters and description
|
|
@@ -723,9 +723,9 @@ class BaseWorkflow(Generic[InputsType, StateType], BaseExecutable, metaclass=_Ba
|
|
|
723
723
|
workflows.append(attr)
|
|
724
724
|
|
|
725
725
|
if len(workflows) == 0:
|
|
726
|
-
raise
|
|
726
|
+
raise WorkflowInitializationException(f"No workflows found in {module_path}")
|
|
727
727
|
elif len(workflows) > 1:
|
|
728
|
-
raise
|
|
728
|
+
raise WorkflowInitializationException(f"Multiple workflows found in {module_path}")
|
|
729
729
|
return workflows[0]
|
|
730
730
|
|
|
731
731
|
def join(self) -> None:
|
|
@@ -22,7 +22,7 @@ vellum_cli/tests/test_ping.py,sha256=b3aQLd-N59_8w2rRiWqwpB1rlHaKEYVbAj1Y3hi7A-g
|
|
|
22
22
|
vellum_cli/tests/test_pull.py,sha256=e2XHzcHIx9k-FyuNAl7wMSNsSSebPGyP6U05JGcddFs,49447
|
|
23
23
|
vellum_cli/tests/test_push.py,sha256=oQ3x28G6IxplmMWCcPEYY46nOYAEPaihcMVsN4quQ5Q,45000
|
|
24
24
|
vellum_ee/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
-
vellum_ee/assets/node-definitions.json,sha256=
|
|
25
|
+
vellum_ee/assets/node-definitions.json,sha256=FHw1RlnD7n8nHBSN9hMsrjBGq9SnM2wga7URiSCDGBY,31408
|
|
26
26
|
vellum_ee/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
27
|
vellum_ee/scripts/generate_node_definitions.py,sha256=FOYQsXIqU45I0OAcsyZUGODF9JK44yunf58rR6YaAdA,3303
|
|
28
28
|
vellum_ee/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -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=2sToAwhdVCU0DssQhHcGwC2r1rQCloW18-mp12JZeqs,20332
|
|
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
|
|
@@ -41,23 +41,23 @@ vellum_ee/workflows/display/nodes/utils.py,sha256=sloya5TpXsnot1HURc9L51INwflRqU
|
|
|
41
41
|
vellum_ee/workflows/display/nodes/vellum/__init__.py,sha256=nUIgH2s0-7IbQRNrBhLPyRNe8YIrx3Yo9HeeW-aXXFk,1668
|
|
42
42
|
vellum_ee/workflows/display/nodes/vellum/api_node.py,sha256=nCtFc5f9u0-OOZvVcMZtc6wwq7MyqAGATH-jPgRTMNM,9028
|
|
43
43
|
vellum_ee/workflows/display/nodes/vellum/base_adornment_node.py,sha256=FHhPoGmmny4Xcxi2pm12Sk3ZOREanWEVrOWcjRhncH4,6337
|
|
44
|
-
vellum_ee/workflows/display/nodes/vellum/code_execution_node.py,sha256=
|
|
45
|
-
vellum_ee/workflows/display/nodes/vellum/conditional_node.py,sha256=
|
|
46
|
-
vellum_ee/workflows/display/nodes/vellum/error_node.py,sha256=
|
|
47
|
-
vellum_ee/workflows/display/nodes/vellum/final_output_node.py,sha256=
|
|
48
|
-
vellum_ee/workflows/display/nodes/vellum/guardrail_node.py,sha256=
|
|
49
|
-
vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=
|
|
50
|
-
vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py,sha256=
|
|
51
|
-
vellum_ee/workflows/display/nodes/vellum/map_node.py,sha256=
|
|
52
|
-
vellum_ee/workflows/display/nodes/vellum/merge_node.py,sha256=
|
|
53
|
-
vellum_ee/workflows/display/nodes/vellum/note_node.py,sha256=
|
|
54
|
-
vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py,sha256=
|
|
44
|
+
vellum_ee/workflows/display/nodes/vellum/code_execution_node.py,sha256=4fuMztGTeyNeg_JFDaVsbM-MFB-RMQwAF9iCpkO7Coc,5173
|
|
45
|
+
vellum_ee/workflows/display/nodes/vellum/conditional_node.py,sha256=lzYPDO7JRdIKshbwPJr7u6QsjAJuRPFz7PSbqewhPJM,11519
|
|
46
|
+
vellum_ee/workflows/display/nodes/vellum/error_node.py,sha256=BXNgRk9YY6CZT056ManeIqsJbEnkDui_JPe47Xy6VVw,2287
|
|
47
|
+
vellum_ee/workflows/display/nodes/vellum/final_output_node.py,sha256=SPMrXqDIJ_YBlnjjdF5ymH5stPkp4apyCLYRBjJep9M,3021
|
|
48
|
+
vellum_ee/workflows/display/nodes/vellum/guardrail_node.py,sha256=gNa5COUKKO1VioJAg2ZWxpNKbY5aAfHN9QYAcS2HJF0,2194
|
|
49
|
+
vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=JQ-dmkgdBuQisY7ycKd_BNEjaZ6EnHm61S1BALBOUxE,12188
|
|
50
|
+
vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py,sha256=ocpe8sHbievEqUix4a7psjFvTrjGBuGrzz_uGU1wnPw,6461
|
|
51
|
+
vellum_ee/workflows/display/nodes/vellum/map_node.py,sha256=LZHY8XZLzHHWUQdk70KHOLMJb17jeZVjvy7VAWP8wzg,4318
|
|
52
|
+
vellum_ee/workflows/display/nodes/vellum/merge_node.py,sha256=S39Oo8PXHbvSwOjtFcXE-Cg4Dey6GveNtR0wQnzUQ34,3137
|
|
53
|
+
vellum_ee/workflows/display/nodes/vellum/note_node.py,sha256=_jOqj1IFfwYNVBgL4ZbSl46utM-aVGsFBT7joL3YHUw,1047
|
|
54
|
+
vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py,sha256=32DgNokx8ZvsEn19zE-rz6zFlj1BG8PE8cZ2TlpzWDk,3730
|
|
55
55
|
vellum_ee/workflows/display/nodes/vellum/retry_node.py,sha256=5xv5OR4xRuI1R5yqJDZTNdCFYY-z8PkTdpWM4ziGjw0,3192
|
|
56
|
-
vellum_ee/workflows/display/nodes/vellum/search_node.py,sha256=
|
|
57
|
-
vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py,sha256=
|
|
58
|
-
vellum_ee/workflows/display/nodes/vellum/templating_node.py,sha256=
|
|
56
|
+
vellum_ee/workflows/display/nodes/vellum/search_node.py,sha256=z_D2VOwt1YUkBMiChzsnObhVHIseqGtQzRoMeREMn54,12058
|
|
57
|
+
vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py,sha256=99Jv6QYAcavrm00MhcCXVDno7ZQzdtfmj_FPvXfMGvk,3152
|
|
58
|
+
vellum_ee/workflows/display/nodes/vellum/templating_node.py,sha256=Ne6BGRdqVhiSrCraY06u2TXMArRmP6Qahj1XBsUgI-4,3184
|
|
59
59
|
vellum_ee/workflows/display/nodes/vellum/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
60
|
-
vellum_ee/workflows/display/nodes/vellum/tests/test_api_node.py,sha256=
|
|
60
|
+
vellum_ee/workflows/display/nodes/vellum/tests/test_api_node.py,sha256=vHV5MThwb0caYfNp5ZoPnYcHwld5CgCOIjTmtxNvDd0,2661
|
|
61
61
|
vellum_ee/workflows/display/nodes/vellum/tests/test_code_execution_node.py,sha256=6_1yVYftVnqXJn3hLUGHlcHvbgKbQgBfS6vYQ6R79oc,10891
|
|
62
62
|
vellum_ee/workflows/display/nodes/vellum/tests/test_error_node.py,sha256=540FoWMpJ3EN_DPjHsr9ODJWCRVcUa5hZBn-5T2GiHU,1665
|
|
63
63
|
vellum_ee/workflows/display/nodes/vellum/tests/test_final_output_node.py,sha256=KVftEQxXARlcr-Uuo1ZK_wEHTcTH64OZJ3Ub3mN8x7I,3006
|
|
@@ -84,7 +84,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attr
|
|
|
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
|
|
87
|
-
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py,sha256=
|
|
87
|
+
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py,sha256=NLvHs8dXG3JiSC2HDUT1-Qi0xvRKuxbtcrTRiWI59SU,16909
|
|
88
88
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py,sha256=arl-tho6f0qstUM2ejONEO4ru_6TxCPbni3FS-UZouQ,30108
|
|
89
89
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py,sha256=-BiFVw3JUx_79isQNgAtZB2362oByRcuAuUVK9uzCJI,54204
|
|
90
90
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_default_state_serialization.py,sha256=E1ww97BFoGbnRkxf84TScat5NQhP8nLVrdaOlpGnSKU,8615
|
|
@@ -110,7 +110,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling
|
|
|
110
110
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py,sha256=pLCyMScV88DTBXRH7jXaXOEA1GBq8NIipCUFwIAWnwI,2771
|
|
111
111
|
vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py,sha256=exT7U-axwtYgFylagScflSQLJEND51qIAx2UATju6JM,6023
|
|
112
112
|
vellum_ee/workflows/display/tests/workflow_serialization/test_final_output_node_map_reference_serialization.py,sha256=vl3pxUJlrYRA8zzFJ-gRm7fe-5fviLNSIsUC7imnMqk,3502
|
|
113
|
-
vellum_ee/workflows/display/tests/workflow_serialization/test_manual_trigger_serialization.py,sha256=
|
|
113
|
+
vellum_ee/workflows/display/tests/workflow_serialization/test_manual_trigger_serialization.py,sha256=L4bJWW94eq5cl6pjIaX7pQrDHoF67Gudfx-41dmmd10,2330
|
|
114
114
|
vellum_ee/workflows/display/tests/workflow_serialization/test_slack_trigger_serialization.py,sha256=lBCzNJHmP_Z7_QEnzBO2FYvjJzVm8-lHxb9buivrqZk,4971
|
|
115
115
|
vellum_ee/workflows/display/tests/workflow_serialization/test_terminal_node_any_serialization.py,sha256=4WAmSEJZlDBLPhsD1f4GwY9ahB9F6qJKGnL6j7ZYlzQ,1740
|
|
116
116
|
vellum_ee/workflows/display/tests/workflow_serialization/test_web_search_node_serialization.py,sha256=vbDFBrWUPeeW7cxjNA6SXrsHlYcbOAhlQ4C45Vdnr1c,3428
|
|
@@ -120,7 +120,7 @@ vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
|
|
|
120
120
|
vellum_ee/workflows/display/utils/auto_layout.py,sha256=f4GiLn_LazweupfqTpubcdtdfE_vrOcmZudSsnYIY9E,3906
|
|
121
121
|
vellum_ee/workflows/display/utils/events.py,sha256=DE33uoKW78BZtITJ6L22dMZN3KR1BuZBVC98C_gIyzU,1943
|
|
122
122
|
vellum_ee/workflows/display/utils/exceptions.py,sha256=E8Lvo7LY1BoZ54M_NR_opDjJsAAiCUfow1HgoHcTHmg,989
|
|
123
|
-
vellum_ee/workflows/display/utils/expressions.py,sha256=
|
|
123
|
+
vellum_ee/workflows/display/utils/expressions.py,sha256=9rcpoXhUIxcWy407Ziu-zJfP5OEFq3pHIh7XSZZ1Y6E,21169
|
|
124
124
|
vellum_ee/workflows/display/utils/registry.py,sha256=1qXiBTdsnro6FeCX0FGBEK7CIf6wa--Jt50iZ_nEp_M,3460
|
|
125
125
|
vellum_ee/workflows/display/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
126
126
|
vellum_ee/workflows/display/utils/tests/test_auto_layout.py,sha256=vfXI769418s9vda5Gb5NFBH747WMOwSgHRXeLCTLVm8,2356
|
|
@@ -128,7 +128,7 @@ vellum_ee/workflows/display/utils/tests/test_events.py,sha256=42IEBnMbaQrH8gigw5
|
|
|
128
128
|
vellum_ee/workflows/display/utils/vellum.py,sha256=Bt7kdLdXoBsHn5dVEY2uKcF542VL09jwu8J_30rl2vk,6413
|
|
129
129
|
vellum_ee/workflows/display/vellum.py,sha256=J2mdJZ1sdLW535DDUkq_Vm8Z572vhuxHxVZF9deKSdk,391
|
|
130
130
|
vellum_ee/workflows/display/workflows/__init__.py,sha256=JTB9ObEV3l4gGGdtfBHwVJtTTKC22uj-a-XjTVwXCyA,148
|
|
131
|
-
vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=
|
|
131
|
+
vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=rY-mK4dLouCUtsq8TAm2ufkODVn8E2_OXix5-Ig0EHA,47629
|
|
132
132
|
vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=gxz76AeCqgAZ9D2lZeTiZzxY9eMgn3qOSfVgiqYcOh8,2028
|
|
133
133
|
vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=lg-c_3P3ldtqWq2VFsk_2Mkn3pVdXWuT59QpH7QwXVs,39764
|
|
134
134
|
vellum_ee/workflows/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -162,7 +162,7 @@ vellum/client/README.md,sha256=flqu57ubZNTfpq60CdLtJC9gp4WEkyjb_n_eZ4OYf9w,6497
|
|
|
162
162
|
vellum/client/__init__.py,sha256=rMnKRqL5-356SBc-rfm56MkO87PuAi2mtcfBszcJU1M,74316
|
|
163
163
|
vellum/client/core/__init__.py,sha256=lTcqUPXcx4112yLDd70RAPeqq6tu3eFMe1pKOqkW9JQ,1562
|
|
164
164
|
vellum/client/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
|
|
165
|
-
vellum/client/core/client_wrapper.py,sha256=
|
|
165
|
+
vellum/client/core/client_wrapper.py,sha256=SDfeITPfYIuFYtFxDzo3M3ePxfx4Mu0Yw6Y3QEnkCts,2840
|
|
166
166
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
|
167
167
|
vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
|
|
168
168
|
vellum/client/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
|
|
@@ -1809,7 +1809,7 @@ vellum/workflows/emitters/vellum_emitter.py,sha256=t4ixrN0NNXrydMP9PVKYvcOMxoMqs
|
|
|
1809
1809
|
vellum/workflows/environment/__init__.py,sha256=TJz0m9dwIs6YOwCTeuN0HHsU-ecyjc1OJXx4AFy83EQ,121
|
|
1810
1810
|
vellum/workflows/environment/environment.py,sha256=Ck3RPKXJvtMGx_toqYQQQF-ZwXm5ijVwJpEPTeIJ4_Q,471
|
|
1811
1811
|
vellum/workflows/errors/__init__.py,sha256=tWGPu5xyAU8gRb8_bl0fL7OfU3wxQ9UH6qVwy4X4P_Q,113
|
|
1812
|
-
vellum/workflows/errors/types.py,sha256=
|
|
1812
|
+
vellum/workflows/errors/types.py,sha256=TgWRhhsLLfiQ5Wxk26Dr01clPTYlq3pM-4umDTXLhWQ,4953
|
|
1813
1813
|
vellum/workflows/events/__init__.py,sha256=V4mh766fyA70WvHelm9kfVZGrUgEKcJ9tJt8EepfQYU,832
|
|
1814
1814
|
vellum/workflows/events/context.py,sha256=vCfMIPmz4j9Om36rRWa35A_JU_VccWWS52_mZkkqxak,3345
|
|
1815
1815
|
vellum/workflows/events/exception_handling.py,sha256=2okFtCzrOzaCP-HEwBPMvHn-evlyyE1zRkmIYjR__jQ,1975
|
|
@@ -1868,7 +1868,7 @@ vellum/workflows/expressions/tests/test_length.py,sha256=pQA1tYSwqxE6euclboY024N
|
|
|
1868
1868
|
vellum/workflows/expressions/tests/test_minus.py,sha256=pq7dvdRGNhSSn95LGNzRErsYUsFk5SpOKHDcSR5QToc,1632
|
|
1869
1869
|
vellum/workflows/expressions/tests/test_parse_json.py,sha256=zpB_qE5_EwWQL7ULQUJm0o1PRSfWZdAqZNW6Ah13oJE,1059
|
|
1870
1870
|
vellum/workflows/graph/__init__.py,sha256=3sHlay5d_-uD7j3QJXiGl0WHFZZ_QScRvgyDhN2GhHY,74
|
|
1871
|
-
vellum/workflows/graph/graph.py,sha256=
|
|
1871
|
+
vellum/workflows/graph/graph.py,sha256=2Yyp6qhm0qcbmbdXS8ZW2jwWFdhSQD2w7hJ2-ltolvs,14687
|
|
1872
1872
|
vellum/workflows/graph/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
1873
1873
|
vellum/workflows/graph/tests/test_graph.py,sha256=OLGkEQh-B1CucwSf4nOP79RFXB4R2isHo3LFlr-24yA,20132
|
|
1874
1874
|
vellum/workflows/inputs/__init__.py,sha256=02pj0IbJkN1AxTreswK39cNi45tA8GWcAAdRJve4cuM,116
|
|
@@ -2027,7 +2027,7 @@ vellum/workflows/resolvers/resolver.py,sha256=3uEYscB_2PHTazc0Y9SzOe_yiQZhVLfey1
|
|
|
2027
2027
|
vellum/workflows/resolvers/tests/test_resolver.py,sha256=PnUGzsulo1It_LjjhHsRNiILvvl5G_IaK8ZX56zKC28,6204
|
|
2028
2028
|
vellum/workflows/resolvers/types.py,sha256=Hndhlk69g6EKLh_LYg5ILepW5U_h_BYNllfzhS9k8p4,237
|
|
2029
2029
|
vellum/workflows/runner/__init__.py,sha256=i1iG5sAhtpdsrlvwgH6B-m49JsINkiWyPWs8vyT-bqM,72
|
|
2030
|
-
vellum/workflows/runner/runner.py,sha256=
|
|
2030
|
+
vellum/workflows/runner/runner.py,sha256=hmr7DIt8Yo2VzVLDVjVBx366foQQVNu6iBBkQjoNNls,46141
|
|
2031
2031
|
vellum/workflows/sandbox.py,sha256=mezSZmilR_fwR8164n8CEfzlMeQ55IqfapHp4ftImvQ,3212
|
|
2032
2032
|
vellum/workflows/state/__init__.py,sha256=yUUdR-_Vl7UiixNDYQZ-GEM_kJI9dnOia75TtuNEsnE,60
|
|
2033
2033
|
vellum/workflows/state/base.py,sha256=8Zr7UIM_eC0O2N6w_1gYqyrjgJ9D9z-VqLFnBETEF7Q,26753
|
|
@@ -2060,7 +2060,7 @@ vellum/workflows/types/tests/test_definition.py,sha256=QUI9_Wsm2k-ZxQTXogsB0L4cs
|
|
|
2060
2060
|
vellum/workflows/types/tests/test_utils.py,sha256=UnZog59tR577mVwqZRqqWn2fScoOU1H6up0EzS8zYhw,2536
|
|
2061
2061
|
vellum/workflows/types/utils.py,sha256=mTctHITBybpt4855x32oCKALBEcMNLn-9cCmfEKgJHQ,6498
|
|
2062
2062
|
vellum/workflows/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2063
|
-
vellum/workflows/utils/functions.py,sha256=
|
|
2063
|
+
vellum/workflows/utils/functions.py,sha256=uIg8As0c1BGwXmwectbAQWLWWIWoeHCduGhhoOqQVVU,13157
|
|
2064
2064
|
vellum/workflows/utils/hmac.py,sha256=JJCczc6pyV6DuE1Oa0QVfYPUN_of3zEYmGFib3OZnrE,1135
|
|
2065
2065
|
vellum/workflows/utils/names.py,sha256=QtHquoaGqRseu5gg2OcVGI2d_CMcEOvjb9KspwH4C-A,552
|
|
2066
2066
|
vellum/workflows/utils/pydantic_schema.py,sha256=eR_bBtY-T0pttJP-ARwagSdCOnwPUtiT3cegm2lzDTQ,1310
|
|
@@ -2074,13 +2074,13 @@ vellum/workflows/utils/vellum_variables.py,sha256=X3lZn-EoWengRWBWRhTNW7hqbj7LkV
|
|
|
2074
2074
|
vellum/workflows/utils/zip.py,sha256=HVg_YZLmBOTXKaDV3Xhaf3V6sYnfqqZXQ8CpuafkbPY,1181
|
|
2075
2075
|
vellum/workflows/vellum_client.py,sha256=3iDR7VV_NgLSm1iZQCKDvrmfEaX1bOJiU15QrxyHpv0,1237
|
|
2076
2076
|
vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
|
|
2077
|
-
vellum/workflows/workflows/base.py,sha256=
|
|
2077
|
+
vellum/workflows/workflows/base.py,sha256=9ILdqYIfB6rIpP-3QeQTOgYeCohjR7xC6c9BqCuAvb4,30977
|
|
2078
2078
|
vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
|
|
2079
2079
|
vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2080
2080
|
vellum/workflows/workflows/tests/test_base_workflow.py,sha256=Boa-_m9ii2Qsa1RvVM-VYniF7zCpzGgEGy-OnPZkrHg,23941
|
|
2081
2081
|
vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
|
|
2082
|
-
vellum_ai-1.7.
|
|
2083
|
-
vellum_ai-1.7.
|
|
2084
|
-
vellum_ai-1.7.
|
|
2085
|
-
vellum_ai-1.7.
|
|
2086
|
-
vellum_ai-1.7.
|
|
2082
|
+
vellum_ai-1.7.9.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
|
2083
|
+
vellum_ai-1.7.9.dist-info/METADATA,sha256=W9uh0R7Qv8FtGnts5F2-3PAMz4ki8JwFXCa43kinV8U,5547
|
|
2084
|
+
vellum_ai-1.7.9.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
2085
|
+
vellum_ai-1.7.9.dist-info/entry_points.txt,sha256=xVavzAKN4iF_NbmhWOlOkHluka0YLkbN_pFQ9pW3gLI,117
|
|
2086
|
+
vellum_ai-1.7.9.dist-info/RECORD,,
|
|
@@ -46,6 +46,32 @@
|
|
|
46
46
|
"type": "DEFAULT"
|
|
47
47
|
}
|
|
48
48
|
],
|
|
49
|
+
"outputs": [
|
|
50
|
+
{
|
|
51
|
+
"id": "99a8d2c4-080f-4605-810e-f5084a52f019",
|
|
52
|
+
"name": "headers",
|
|
53
|
+
"type": "JSON",
|
|
54
|
+
"value": null
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "c5737084-f688-4695-ab81-5f97a6b1a5c2",
|
|
58
|
+
"name": "json",
|
|
59
|
+
"type": "JSON",
|
|
60
|
+
"value": null
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"id": "a2a63a64-75f1-49ba-8743-4db660179ab3",
|
|
64
|
+
"name": "status_code",
|
|
65
|
+
"type": "NUMBER",
|
|
66
|
+
"value": null
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "baa40ce0-35e7-4439-b280-085aaf4f54da",
|
|
70
|
+
"name": "text",
|
|
71
|
+
"type": "STRING",
|
|
72
|
+
"value": null
|
|
73
|
+
}
|
|
74
|
+
],
|
|
49
75
|
"attributes": [
|
|
50
76
|
{
|
|
51
77
|
"id": "aacb36f1-c980-460d-8002-43bb57128e05",
|
|
@@ -747,48 +773,6 @@
|
|
|
747
773
|
{
|
|
748
774
|
"id": "035842e0-34ed-43af-97de-a706e40912ae",
|
|
749
775
|
"label": "Tool Calling Node",
|
|
750
|
-
"display_data": {
|
|
751
|
-
"position": {
|
|
752
|
-
"x": 0.0,
|
|
753
|
-
"y": 0.0
|
|
754
|
-
},
|
|
755
|
-
"comment": {
|
|
756
|
-
"value": "\n A Node that dynamically invokes the provided functions to the underlying Prompt\n\n Attributes:\n ml_model: str - The model to use for tool calling (e.g., \"gpt-4o-mini\")\n blocks: List[PromptBlock] - The prompt blocks to use (same format as InlinePromptNode)\n functions: List[Tool] - The functions that can be called\n prompt_inputs: Optional[EntityInputsInterface] - Mapping of input variable names to values\n parameters: PromptParameters - The parameters for the Prompt\n max_prompt_iterations: Optional[int] - Maximum number of prompt iterations before stopping\n ",
|
|
757
|
-
"expanded": true
|
|
758
|
-
}
|
|
759
|
-
},
|
|
760
|
-
"base": {
|
|
761
|
-
"name": "BaseNode",
|
|
762
|
-
"module": [
|
|
763
|
-
"vellum",
|
|
764
|
-
"workflows",
|
|
765
|
-
"nodes",
|
|
766
|
-
"bases",
|
|
767
|
-
"base"
|
|
768
|
-
]
|
|
769
|
-
},
|
|
770
|
-
"definition": {
|
|
771
|
-
"name": "ToolCallingNode",
|
|
772
|
-
"module": [
|
|
773
|
-
"vellum",
|
|
774
|
-
"workflows",
|
|
775
|
-
"nodes",
|
|
776
|
-
"displayable",
|
|
777
|
-
"tool_calling_node",
|
|
778
|
-
"node"
|
|
779
|
-
]
|
|
780
|
-
},
|
|
781
|
-
"trigger": {
|
|
782
|
-
"id": "f9b4a4ce-68ae-45f4-9e29-38b588abdf97",
|
|
783
|
-
"merge_behavior": "AWAIT_ATTRIBUTES"
|
|
784
|
-
},
|
|
785
|
-
"ports": [
|
|
786
|
-
{
|
|
787
|
-
"id": "72157fce-fc16-44d8-a00d-506738a20730",
|
|
788
|
-
"name": "default",
|
|
789
|
-
"type": "DEFAULT"
|
|
790
|
-
}
|
|
791
|
-
],
|
|
792
776
|
"attributes": [
|
|
793
777
|
{
|
|
794
778
|
"id": "df3761db-067a-4fe9-9fc3-ba270786fcf6",
|
|
@@ -878,31 +862,13 @@
|
|
|
878
862
|
}
|
|
879
863
|
}
|
|
880
864
|
],
|
|
881
|
-
"outputs": [
|
|
882
|
-
{
|
|
883
|
-
"id": "c18a8725-21e1-4736-a77c-76d0fc035176",
|
|
884
|
-
"name": "text",
|
|
885
|
-
"type": "STRING",
|
|
886
|
-
"value": null
|
|
887
|
-
},
|
|
888
|
-
{
|
|
889
|
-
"id": "5a9ad073-c670-43d2-9198-a08e9fdda7ad",
|
|
890
|
-
"name": "chat_history",
|
|
891
|
-
"type": "CHAT_HISTORY",
|
|
892
|
-
"value": null
|
|
893
|
-
}
|
|
894
|
-
]
|
|
895
|
-
},
|
|
896
|
-
{
|
|
897
|
-
"id": "187ed9ed-ca2b-49e4-943d-ee8da5fad973",
|
|
898
|
-
"label": "Web Search Node",
|
|
899
865
|
"display_data": {
|
|
900
866
|
"position": {
|
|
901
867
|
"x": 0.0,
|
|
902
868
|
"y": 0.0
|
|
903
869
|
},
|
|
904
870
|
"comment": {
|
|
905
|
-
"value": "\n
|
|
871
|
+
"value": "\n A Node that dynamically invokes the provided functions to the underlying Prompt\n\n Attributes:\n ml_model: str - The model to use for tool calling (e.g., \"gpt-4o-mini\")\n blocks: List[PromptBlock] - The prompt blocks to use (same format as InlinePromptNode)\n functions: List[Tool] - The functions that can be called\n prompt_inputs: Optional[EntityInputsInterface] - Mapping of input variable names to values\n parameters: PromptParameters - The parameters for the Prompt\n max_prompt_iterations: Optional[int] - Maximum number of prompt iterations before stopping\n ",
|
|
906
872
|
"expanded": true
|
|
907
873
|
}
|
|
908
874
|
},
|
|
@@ -917,27 +883,45 @@
|
|
|
917
883
|
]
|
|
918
884
|
},
|
|
919
885
|
"definition": {
|
|
920
|
-
"name": "
|
|
886
|
+
"name": "ToolCallingNode",
|
|
921
887
|
"module": [
|
|
922
888
|
"vellum",
|
|
923
889
|
"workflows",
|
|
924
890
|
"nodes",
|
|
925
891
|
"displayable",
|
|
926
|
-
"
|
|
892
|
+
"tool_calling_node",
|
|
927
893
|
"node"
|
|
928
894
|
]
|
|
929
895
|
},
|
|
930
896
|
"trigger": {
|
|
931
|
-
"id": "
|
|
897
|
+
"id": "f9b4a4ce-68ae-45f4-9e29-38b588abdf97",
|
|
932
898
|
"merge_behavior": "AWAIT_ATTRIBUTES"
|
|
933
899
|
},
|
|
934
900
|
"ports": [
|
|
935
901
|
{
|
|
936
|
-
"id": "
|
|
902
|
+
"id": "72157fce-fc16-44d8-a00d-506738a20730",
|
|
937
903
|
"name": "default",
|
|
938
904
|
"type": "DEFAULT"
|
|
939
905
|
}
|
|
940
906
|
],
|
|
907
|
+
"outputs": [
|
|
908
|
+
{
|
|
909
|
+
"id": "c18a8725-21e1-4736-a77c-76d0fc035176",
|
|
910
|
+
"name": "text",
|
|
911
|
+
"type": "STRING",
|
|
912
|
+
"value": null
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
"id": "5a9ad073-c670-43d2-9198-a08e9fdda7ad",
|
|
916
|
+
"name": "chat_history",
|
|
917
|
+
"type": "CHAT_HISTORY",
|
|
918
|
+
"value": null
|
|
919
|
+
}
|
|
920
|
+
]
|
|
921
|
+
},
|
|
922
|
+
{
|
|
923
|
+
"id": "187ed9ed-ca2b-49e4-943d-ee8da5fad973",
|
|
924
|
+
"label": "Web Search Node",
|
|
941
925
|
"attributes": [
|
|
942
926
|
{
|
|
943
927
|
"id": "b5ba3c60-e02c-46c8-b470-d86c4f8f42af",
|
|
@@ -984,6 +968,48 @@
|
|
|
984
968
|
}
|
|
985
969
|
}
|
|
986
970
|
],
|
|
971
|
+
"display_data": {
|
|
972
|
+
"position": {
|
|
973
|
+
"x": 0.0,
|
|
974
|
+
"y": 0.0
|
|
975
|
+
},
|
|
976
|
+
"comment": {
|
|
977
|
+
"value": "\n Used to perform web search using SerpAPI.\n\n query: str - The search query to execute\n api_key: str - SerpAPI authentication key\n num_results: int - Number of search results to return (default: 10)\n location: Optional[str] - Geographic location filter for search\n ",
|
|
978
|
+
"expanded": true
|
|
979
|
+
}
|
|
980
|
+
},
|
|
981
|
+
"base": {
|
|
982
|
+
"name": "BaseNode",
|
|
983
|
+
"module": [
|
|
984
|
+
"vellum",
|
|
985
|
+
"workflows",
|
|
986
|
+
"nodes",
|
|
987
|
+
"bases",
|
|
988
|
+
"base"
|
|
989
|
+
]
|
|
990
|
+
},
|
|
991
|
+
"definition": {
|
|
992
|
+
"name": "WebSearchNode",
|
|
993
|
+
"module": [
|
|
994
|
+
"vellum",
|
|
995
|
+
"workflows",
|
|
996
|
+
"nodes",
|
|
997
|
+
"displayable",
|
|
998
|
+
"web_search_node",
|
|
999
|
+
"node"
|
|
1000
|
+
]
|
|
1001
|
+
},
|
|
1002
|
+
"trigger": {
|
|
1003
|
+
"id": "036c7a0c-fff3-44f7-b49b-429d8f44f212",
|
|
1004
|
+
"merge_behavior": "AWAIT_ATTRIBUTES"
|
|
1005
|
+
},
|
|
1006
|
+
"ports": [
|
|
1007
|
+
{
|
|
1008
|
+
"id": "ef824748-d00d-41e7-b7b4-d0edc536c3af",
|
|
1009
|
+
"name": "default",
|
|
1010
|
+
"type": "DEFAULT"
|
|
1011
|
+
}
|
|
1012
|
+
],
|
|
987
1013
|
"outputs": [
|
|
988
1014
|
{
|
|
989
1015
|
"id": "704a4ba3-1afe-482d-876a-91dcdbe90fb7",
|
|
@@ -8,6 +8,7 @@ from typing import (
|
|
|
8
8
|
Dict,
|
|
9
9
|
ForwardRef,
|
|
10
10
|
Generic,
|
|
11
|
+
List,
|
|
11
12
|
Optional,
|
|
12
13
|
Set,
|
|
13
14
|
Tuple,
|
|
@@ -183,32 +184,13 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
|
|
|
183
184
|
existing_adornments = adornments if adornments is not None else []
|
|
184
185
|
return display_class().serialize(display_context, adornments=existing_adornments + [adornment])
|
|
185
186
|
|
|
186
|
-
outputs: JsonArray = []
|
|
187
|
-
for output in node.Outputs:
|
|
188
|
-
type = primitive_type_to_vellum_variable_type(output)
|
|
189
|
-
value = (
|
|
190
|
-
serialize_value(node_id, display_context, output.instance)
|
|
191
|
-
if output.instance is not None and output.instance is not undefined
|
|
192
|
-
else None
|
|
193
|
-
)
|
|
194
|
-
|
|
195
|
-
outputs.append(
|
|
196
|
-
{
|
|
197
|
-
"id": str(uuid4_from_hash(f"{node_id}|{output.name}")),
|
|
198
|
-
"name": output.name,
|
|
199
|
-
"type": type,
|
|
200
|
-
"value": value,
|
|
201
|
-
}
|
|
202
|
-
)
|
|
203
|
-
|
|
204
187
|
return {
|
|
205
188
|
"id": str(node_id),
|
|
206
189
|
"label": self.label,
|
|
207
190
|
"type": "GENERIC",
|
|
208
|
-
**self.serialize_generic_fields(display_context),
|
|
209
191
|
"adornments": adornments,
|
|
210
192
|
"attributes": attributes,
|
|
211
|
-
|
|
193
|
+
**self.serialize_generic_fields(display_context),
|
|
212
194
|
}
|
|
213
195
|
|
|
214
196
|
def serialize_ports(self, display_context: "WorkflowDisplayContext") -> JsonArray:
|
|
@@ -275,14 +257,49 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
|
|
|
275
257
|
|
|
276
258
|
return attributes
|
|
277
259
|
|
|
278
|
-
def
|
|
260
|
+
def _serialize_outputs(self, display_context: "WorkflowDisplayContext") -> JsonArray:
|
|
261
|
+
"""Generate outputs array from node output displays or node.Outputs."""
|
|
262
|
+
outputs: JsonArray = []
|
|
263
|
+
node = self._node
|
|
264
|
+
|
|
265
|
+
for output in node.Outputs:
|
|
266
|
+
output_type = primitive_type_to_vellum_variable_type(output)
|
|
267
|
+
value = (
|
|
268
|
+
serialize_value(self.node_id, display_context, output.instance)
|
|
269
|
+
if output.instance is not None and output.instance != undefined
|
|
270
|
+
else None
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
output_id = (
|
|
274
|
+
str(self.output_display[output].id)
|
|
275
|
+
if output in self.output_display
|
|
276
|
+
else str(uuid4_from_hash(f"{self.node_id}|{output.name}"))
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
outputs.append(
|
|
280
|
+
{
|
|
281
|
+
"id": output_id,
|
|
282
|
+
"name": output.name,
|
|
283
|
+
"type": output_type,
|
|
284
|
+
"value": value,
|
|
285
|
+
}
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
return outputs
|
|
289
|
+
|
|
290
|
+
def serialize_generic_fields(
|
|
291
|
+
self, display_context: "WorkflowDisplayContext", exclude: Optional[List[str]] = None
|
|
292
|
+
) -> JsonObject:
|
|
279
293
|
"""Serialize generic fields that are common to all nodes."""
|
|
294
|
+
exclude = exclude or []
|
|
295
|
+
|
|
280
296
|
result: JsonObject = {
|
|
281
|
-
"display_data": self.get_display_data().dict(),
|
|
282
|
-
"base": self.get_base().dict(),
|
|
283
|
-
"definition": self.get_definition().dict(),
|
|
284
|
-
"trigger": self.serialize_trigger(),
|
|
285
|
-
"ports": self.serialize_ports(display_context),
|
|
297
|
+
"display_data": self.get_display_data().dict() if "display_data" not in exclude else None,
|
|
298
|
+
"base": self.get_base().dict() if "base" not in exclude else None,
|
|
299
|
+
"definition": self.get_definition().dict() if "definition" not in exclude else None,
|
|
300
|
+
"trigger": self.serialize_trigger() if "trigger" not in exclude else None,
|
|
301
|
+
"ports": self.serialize_ports(display_context) if "ports" not in exclude else None,
|
|
302
|
+
"outputs": self._serialize_outputs(display_context) if "outputs" not in exclude else None,
|
|
286
303
|
}
|
|
287
304
|
|
|
288
305
|
# Only include should_file_merge if there are custom methods defined
|
|
@@ -299,6 +316,9 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
|
|
|
299
316
|
except Exception:
|
|
300
317
|
pass
|
|
301
318
|
|
|
319
|
+
for key in exclude:
|
|
320
|
+
result.pop(key, None)
|
|
321
|
+
|
|
302
322
|
return result
|
|
303
323
|
|
|
304
324
|
def get_base(self) -> CodeResourceDefinition:
|
|
@@ -119,5 +119,5 @@ class BaseCodeExecutionNodeDisplay(BaseNodeDisplay[_CodeExecutionNodeType], Gene
|
|
|
119
119
|
"output_id": str(self.output_id) if self.output_id else str(output_display.id),
|
|
120
120
|
"log_output_id": str(self.log_output_id) if self.log_output_id else str(log_output_display.id),
|
|
121
121
|
},
|
|
122
|
-
**self.serialize_generic_fields(display_context),
|
|
122
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
123
123
|
}
|
|
@@ -217,7 +217,7 @@ but the defined conditions have length {len(condition_ids)}"""
|
|
|
217
217
|
"conditions": conditions, # type: ignore
|
|
218
218
|
"version": "2",
|
|
219
219
|
},
|
|
220
|
-
**self.serialize_generic_fields(display_context),
|
|
220
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
def get_nested_rule_details_by_path(
|
|
@@ -47,7 +47,7 @@ class BaseErrorNodeDisplay(BaseNodeDisplay[_ErrorNodeType], Generic[_ErrorNodeTy
|
|
|
47
47
|
"target_handle_id": str(self.get_target_handle_id()),
|
|
48
48
|
"error_source_input_id": str(error_source_input_id),
|
|
49
49
|
},
|
|
50
|
-
**self.serialize_generic_fields(display_context),
|
|
50
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
if self.name:
|
|
@@ -45,7 +45,7 @@ class BaseFinalOutputNodeDisplay(BaseNodeDisplay[_FinalOutputNodeType], Generic[
|
|
|
45
45
|
"node_input_id": str(node_input.id),
|
|
46
46
|
},
|
|
47
47
|
"inputs": [node_input.dict()],
|
|
48
|
-
**self.serialize_generic_fields(display_context),
|
|
48
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
49
49
|
"outputs": [
|
|
50
50
|
{
|
|
51
51
|
"id": str(self._get_output_id()),
|
|
@@ -45,5 +45,5 @@ class BaseGuardrailNodeDisplay(BaseNodeDisplay[_GuardrailNodeType], Generic[_Gua
|
|
|
45
45
|
"metric_definition_id": str(raise_if_descriptor(node.metric_definition)),
|
|
46
46
|
"release_tag": raise_if_descriptor(node.release_tag),
|
|
47
47
|
},
|
|
48
|
-
**self.serialize_generic_fields(display_context),
|
|
48
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
49
49
|
}
|
|
@@ -110,7 +110,7 @@ class BaseInlinePromptNodeDisplay(BaseNodeDisplay[_InlinePromptNodeType], Generi
|
|
|
110
110
|
},
|
|
111
111
|
"ml_model_name": ml_model,
|
|
112
112
|
},
|
|
113
|
-
**self.serialize_generic_fields(display_context),
|
|
113
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
114
114
|
"outputs": [
|
|
115
115
|
{"id": str(json_display.id), "name": "json", "type": "JSON", "value": None},
|
|
116
116
|
{"id": str(output_display.id), "name": "text", "type": "STRING", "value": None},
|
|
@@ -68,7 +68,7 @@ class BaseInlineSubworkflowNodeDisplay(
|
|
|
68
68
|
"input_variables": [workflow_input.dict() for workflow_input in workflow_inputs],
|
|
69
69
|
"output_variables": [workflow_output.dict() for workflow_output in workflow_outputs],
|
|
70
70
|
},
|
|
71
|
-
**self.serialize_generic_fields(display_context),
|
|
71
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
def _generate_node_and_workflow_inputs(
|
|
@@ -88,7 +88,7 @@ class BaseMapNodeDisplay(BaseAdornmentNodeDisplay[_MapNodeType], Generic[_MapNod
|
|
|
88
88
|
"item_input_id": item_workflow_input_id,
|
|
89
89
|
"index_input_id": index_workflow_input_id,
|
|
90
90
|
},
|
|
91
|
-
**self.serialize_generic_fields(display_context),
|
|
91
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
def _default_workflow_class(self) -> Type[BaseWorkflow]:
|
|
@@ -47,7 +47,7 @@ class BaseMergeNodeDisplay(BaseNodeDisplay[_MergeNodeType], Generic[_MergeNodeTy
|
|
|
47
47
|
"target_handles": [{"id": str(target_handle_id)} for target_handle_id in target_handle_ids],
|
|
48
48
|
"source_handle_id": str(self.get_source_handle_id(display_context.port_displays)),
|
|
49
49
|
},
|
|
50
|
-
**self.serialize_generic_fields(display_context),
|
|
50
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
def get_target_handle_ids(self) -> Optional[List[UUID]]:
|
|
@@ -71,7 +71,7 @@ class BasePromptDeploymentNodeDisplay(BaseNodeDisplay[_PromptDeploymentNodeType]
|
|
|
71
71
|
"release_tag": raise_if_descriptor(node.release_tag),
|
|
72
72
|
"ml_model_fallbacks": list(ml_model_fallbacks) if ml_model_fallbacks else None,
|
|
73
73
|
},
|
|
74
|
-
**self.serialize_generic_fields(display_context),
|
|
74
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
75
75
|
"outputs": [
|
|
76
76
|
{"id": str(json_display.id), "name": "json", "type": "JSON", "value": None},
|
|
77
77
|
{"id": str(output_display.id), "name": "text", "type": "STRING", "value": None},
|
|
@@ -71,7 +71,7 @@ class BaseSearchNodeDisplay(BaseNodeDisplay[_SearchNodeType], Generic[_SearchNod
|
|
|
71
71
|
"external_id_filters_node_input_id": str(node_inputs["external_id_filters"].id),
|
|
72
72
|
"metadata_filters_node_input_id": str(node_inputs["metadata_filters"].id),
|
|
73
73
|
},
|
|
74
|
-
**self.serialize_generic_fields(display_context),
|
|
74
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
def _generate_search_node_inputs(
|
|
@@ -68,5 +68,5 @@ class BaseSubworkflowDeploymentNodeDisplay(
|
|
|
68
68
|
"workflow_deployment_id": deployment_id,
|
|
69
69
|
"release_tag": raise_if_descriptor(node.release_tag),
|
|
70
70
|
},
|
|
71
|
-
**self.serialize_generic_fields(display_context),
|
|
71
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
72
72
|
}
|
|
@@ -66,5 +66,5 @@ class BaseTemplatingNodeDisplay(BaseNodeDisplay[_TemplatingNodeType], Generic[_T
|
|
|
66
66
|
"template_node_input_id": str(template_node_input.id),
|
|
67
67
|
"output_type": inferred_output_type,
|
|
68
68
|
},
|
|
69
|
-
**self.serialize_generic_fields(display_context),
|
|
69
|
+
**self.serialize_generic_fields(display_context, exclude=["outputs"]),
|
|
70
70
|
}
|
|
@@ -29,3 +29,37 @@ def test_serialize_node__api_node_with_timeout():
|
|
|
29
29
|
assert timeout_attribute["value"]["type"] == "CONSTANT_VALUE"
|
|
30
30
|
assert timeout_attribute["value"]["value"]["type"] == "NUMBER"
|
|
31
31
|
assert timeout_attribute["value"]["value"]["value"] == 30.0
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_serialize_node__api_node_outputs():
|
|
35
|
+
"""
|
|
36
|
+
Tests that API node serialization includes the outputs array.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
class MyAPINode(APINode):
|
|
40
|
+
url = "https://api.example.com"
|
|
41
|
+
method = APIRequestMethod.GET
|
|
42
|
+
|
|
43
|
+
class Workflow(BaseWorkflow):
|
|
44
|
+
graph = MyAPINode
|
|
45
|
+
|
|
46
|
+
workflow_display = get_workflow_display(workflow_class=Workflow)
|
|
47
|
+
serialized_workflow: dict = workflow_display.serialize()
|
|
48
|
+
|
|
49
|
+
my_api_node = next(node for node in serialized_workflow["workflow_raw_data"]["nodes"] if node["type"] == "API")
|
|
50
|
+
|
|
51
|
+
assert "outputs" in my_api_node
|
|
52
|
+
outputs = my_api_node["outputs"]
|
|
53
|
+
assert len(outputs) == 4
|
|
54
|
+
|
|
55
|
+
text_output = next(output for output in outputs if output["name"] == "text")
|
|
56
|
+
assert text_output["type"] == "STRING"
|
|
57
|
+
assert text_output["value"] is None
|
|
58
|
+
|
|
59
|
+
json_output = next(output for output in outputs if output["name"] == "json")
|
|
60
|
+
assert json_output["type"] == "JSON"
|
|
61
|
+
assert json_output["value"] is None
|
|
62
|
+
|
|
63
|
+
status_code_output = next(output for output in outputs if output["name"] == "status_code")
|
|
64
|
+
assert status_code_output["type"] == "NUMBER"
|
|
65
|
+
assert status_code_output["value"] is None
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py
CHANGED
|
@@ -8,6 +8,8 @@ from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class imp
|
|
|
8
8
|
|
|
9
9
|
from tests.workflows.basic_api_node.workflow import SimpleAPIWorkflow
|
|
10
10
|
|
|
11
|
+
# 0d76e1e1-3a4b-4eb4-a606-f73d62c -> 12e4a99d-883d-4da5-aa51-35817d94013e
|
|
12
|
+
|
|
11
13
|
|
|
12
14
|
def test_serialize_workflow(vellum_client):
|
|
13
15
|
# GIVEN a Workflow that uses a vellum API node
|
|
@@ -208,6 +210,12 @@ def test_serialize_workflow(vellum_client):
|
|
|
208
210
|
"merge_behavior": "AWAIT_ANY",
|
|
209
211
|
},
|
|
210
212
|
"ports": [{"id": "7c33b4d3-9204-4bd5-9371-80ee34f83073", "name": "default", "type": "DEFAULT"}],
|
|
213
|
+
"outputs": [
|
|
214
|
+
{"id": "12e4a99d-883d-4da5-aa51-35817d94013e", "name": "json", "type": "JSON", "value": None},
|
|
215
|
+
{"id": "0d76e1e1-3a4b-4eb4-a606-f73d62cf1a7e", "name": "headers", "type": "JSON", "value": None},
|
|
216
|
+
{"id": "fecc16c3-400e-4fd3-8223-08366070e3b1", "name": "status_code", "type": "NUMBER", "value": None},
|
|
217
|
+
{"id": "17342c21-12bb-49ab-88ce-f144e0376b32", "name": "text", "type": "STRING", "value": None},
|
|
218
|
+
],
|
|
211
219
|
},
|
|
212
220
|
api_node,
|
|
213
221
|
)
|
vellum_ee/workflows/display/tests/workflow_serialization/test_manual_trigger_serialization.py
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
"""Tests for serialization of workflows with ManualTrigger."""
|
|
2
|
-
|
|
3
1
|
import pytest
|
|
4
|
-
from typing import cast
|
|
5
2
|
|
|
6
3
|
from vellum.workflows import BaseWorkflow
|
|
7
4
|
from vellum.workflows.inputs.base import BaseInputs
|
|
@@ -9,95 +6,55 @@ from vellum.workflows.nodes.bases.base import BaseNode
|
|
|
9
6
|
from vellum.workflows.state.base import BaseState
|
|
10
7
|
from vellum.workflows.triggers.base import BaseTrigger
|
|
11
8
|
from vellum.workflows.triggers.manual import ManualTrigger
|
|
12
|
-
from vellum.workflows.types.core import JsonArray, JsonObject
|
|
13
9
|
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
|
14
10
|
|
|
15
11
|
|
|
16
|
-
class Inputs(BaseInputs):
|
|
17
|
-
input: str
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class SimpleNode(BaseNode):
|
|
21
|
-
class Outputs(BaseNode.Outputs):
|
|
22
|
-
output = Inputs.input
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def create_workflow(trigger=None):
|
|
26
|
-
"""Factory for creating test workflows."""
|
|
27
|
-
|
|
28
|
-
class TestWorkflow(BaseWorkflow[Inputs, BaseState]):
|
|
29
|
-
graph = trigger >> SimpleNode if trigger else SimpleNode
|
|
30
|
-
|
|
31
|
-
class Outputs(BaseWorkflow.Outputs):
|
|
32
|
-
output = SimpleNode.Outputs.output
|
|
33
|
-
|
|
34
|
-
return TestWorkflow
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def serialize(workflow_class) -> JsonObject:
|
|
38
|
-
"""Helper to serialize a workflow."""
|
|
39
|
-
return get_workflow_display(workflow_class=workflow_class).serialize()
|
|
40
|
-
|
|
41
|
-
|
|
42
12
|
def test_manual_trigger_serialization():
|
|
43
13
|
"""Workflow with ManualTrigger serializes with triggers field."""
|
|
44
|
-
result = serialize(create_workflow(ManualTrigger))
|
|
45
|
-
triggers = cast(JsonArray, result["triggers"])
|
|
46
14
|
|
|
47
|
-
|
|
48
|
-
|
|
15
|
+
class SimpleNode(BaseNode):
|
|
16
|
+
pass
|
|
49
17
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
assert "attributes" in trigger
|
|
53
|
-
assert trigger["attributes"] == []
|
|
54
|
-
assert "definition" not in trigger
|
|
18
|
+
class TestWorkflow(BaseWorkflow[BaseInputs, BaseState]):
|
|
19
|
+
graph = ManualTrigger >> SimpleNode
|
|
55
20
|
|
|
21
|
+
result = get_workflow_display(workflow_class=TestWorkflow).serialize()
|
|
22
|
+
assert "triggers" in result
|
|
23
|
+
triggers = result["triggers"]
|
|
24
|
+
assert isinstance(triggers, list)
|
|
56
25
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
result = serialize(create_workflow())
|
|
60
|
-
assert "triggers" not in result
|
|
26
|
+
assert len(triggers) == 1
|
|
27
|
+
assert triggers[0] == {"id": "b09c1902-3cca-4c79-b775-4c32e3e88466", "type": "MANUAL", "attributes": []}
|
|
61
28
|
|
|
62
29
|
|
|
63
30
|
def test_manual_trigger_multiple_entrypoints():
|
|
64
31
|
"""ManualTrigger with multiple entrypoints."""
|
|
65
32
|
|
|
66
33
|
class NodeA(BaseNode):
|
|
67
|
-
|
|
68
|
-
output = Inputs.input
|
|
34
|
+
pass
|
|
69
35
|
|
|
70
36
|
class NodeB(BaseNode):
|
|
71
|
-
|
|
72
|
-
output = Inputs.input
|
|
37
|
+
pass
|
|
73
38
|
|
|
74
|
-
class MultiWorkflow(BaseWorkflow[
|
|
39
|
+
class MultiWorkflow(BaseWorkflow[BaseInputs, BaseState]):
|
|
75
40
|
graph = ManualTrigger >> {NodeA, NodeB}
|
|
76
41
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
workflow_data = cast(JsonObject, result["workflow_raw_data"])
|
|
84
|
-
nodes = cast(JsonArray, workflow_data["nodes"])
|
|
85
|
-
|
|
86
|
-
assert len(triggers) == 1
|
|
87
|
-
trigger = cast(JsonObject, triggers[0])
|
|
88
|
-
assert trigger["type"] == "MANUAL"
|
|
89
|
-
assert len([n for n in nodes if cast(JsonObject, n)["type"] == "GENERIC"]) >= 2
|
|
42
|
+
result = get_workflow_display(workflow_class=MultiWorkflow).serialize()
|
|
43
|
+
workflow_data = result["workflow_raw_data"]
|
|
44
|
+
assert isinstance(workflow_data, dict)
|
|
45
|
+
assert "nodes" in workflow_data
|
|
46
|
+
nodes = workflow_data["nodes"]
|
|
47
|
+
assert isinstance(nodes, list)
|
|
90
48
|
|
|
49
|
+
# entrypoint + 2 nodes
|
|
50
|
+
assert len(nodes) == 3
|
|
91
51
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
workflow_raw_data = cast(JsonObject, result["workflow_raw_data"])
|
|
96
|
-
definition = cast(JsonObject, workflow_raw_data["definition"])
|
|
52
|
+
assert "triggers" in result
|
|
53
|
+
triggers = result["triggers"]
|
|
54
|
+
assert isinstance(triggers, list)
|
|
97
55
|
|
|
98
|
-
assert
|
|
99
|
-
assert
|
|
100
|
-
assert definition["name"] == "TestWorkflow"
|
|
56
|
+
assert len(triggers) == 1
|
|
57
|
+
assert triggers[0] == {"id": "b09c1902-3cca-4c79-b775-4c32e3e88466", "type": "MANUAL", "attributes": []}
|
|
101
58
|
|
|
102
59
|
|
|
103
60
|
def test_unknown_trigger_type():
|
|
@@ -106,5 +63,11 @@ def test_unknown_trigger_type():
|
|
|
106
63
|
class UnknownTrigger(BaseTrigger):
|
|
107
64
|
pass
|
|
108
65
|
|
|
66
|
+
class SimpleNode(BaseNode):
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
class TestWorkflow(BaseWorkflow[BaseInputs, BaseState]):
|
|
70
|
+
graph = UnknownTrigger >> SimpleNode
|
|
71
|
+
|
|
109
72
|
with pytest.raises(ValueError, match="Unknown trigger type: UnknownTrigger"):
|
|
110
|
-
serialize(
|
|
73
|
+
get_workflow_display(workflow_class=TestWorkflow).serialize()
|
|
@@ -50,6 +50,7 @@ from vellum.workflows.references.execution_count import ExecutionCountReference
|
|
|
50
50
|
from vellum.workflows.references.lazy import LazyReference
|
|
51
51
|
from vellum.workflows.references.output import OutputReference
|
|
52
52
|
from vellum.workflows.references.state_value import StateValueReference
|
|
53
|
+
from vellum.workflows.references.trigger import TriggerAttributeReference
|
|
53
54
|
from vellum.workflows.references.vellum_secret import VellumSecretReference
|
|
54
55
|
from vellum.workflows.references.workflow_input import WorkflowInputReference
|
|
55
56
|
from vellum.workflows.types.core import JsonArray, JsonObject
|
|
@@ -347,6 +348,17 @@ def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContex
|
|
|
347
348
|
"node_id": str(node_class_display.node_id),
|
|
348
349
|
}
|
|
349
350
|
|
|
351
|
+
if isinstance(value, TriggerAttributeReference):
|
|
352
|
+
# Generate trigger ID using the same hash formula as in base_workflow_display.py
|
|
353
|
+
trigger_class = value.trigger_class
|
|
354
|
+
trigger_id = uuid4_from_hash(trigger_class.__qualname__)
|
|
355
|
+
|
|
356
|
+
return {
|
|
357
|
+
"type": "TRIGGER_ATTRIBUTE",
|
|
358
|
+
"trigger_id": str(trigger_id),
|
|
359
|
+
"attribute_id": str(value.id),
|
|
360
|
+
}
|
|
361
|
+
|
|
350
362
|
if isinstance(value, list):
|
|
351
363
|
serialized_items = []
|
|
352
364
|
for item in value:
|
|
@@ -474,7 +474,7 @@ class BaseWorkflowDisplay(Generic[WorkflowType]):
|
|
|
474
474
|
)
|
|
475
475
|
|
|
476
476
|
# Return as a list with a single trigger object matching Django schema
|
|
477
|
-
trigger_id = uuid4_from_hash(
|
|
477
|
+
trigger_id = uuid4_from_hash(trigger_class.__qualname__)
|
|
478
478
|
|
|
479
479
|
# Serialize trigger attributes like node outputs
|
|
480
480
|
attribute_references = trigger_class.attribute_references().values()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|