vellum-ai 1.4.1__py3-none-any.whl → 1.4.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vellum/client/core/client_wrapper.py +2 -2
- vellum/workflows/constants.py +4 -0
- vellum/workflows/emitters/base.py +8 -0
- vellum/workflows/emitters/vellum_emitter.py +10 -0
- vellum/workflows/inputs/dataset_row.py +2 -2
- vellum/workflows/nodes/bases/base.py +12 -1
- vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +6 -0
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +16 -2
- vellum/workflows/nodes/displayable/final_output_node/node.py +59 -0
- vellum/workflows/nodes/displayable/final_output_node/tests/test_node.py +40 -1
- vellum/workflows/nodes/displayable/tool_calling_node/node.py +3 -0
- vellum/workflows/nodes/displayable/tool_calling_node/tests/test_utils.py +64 -0
- vellum/workflows/nodes/displayable/tool_calling_node/utils.py +30 -41
- vellum/workflows/tests/test_dataset_row.py +29 -0
- vellum/workflows/types/core.py +13 -2
- vellum/workflows/types/definition.py +13 -1
- vellum/workflows/utils/functions.py +63 -26
- vellum/workflows/utils/tests/test_functions.py +10 -6
- vellum/workflows/vellum_client.py +7 -1
- vellum/workflows/workflows/base.py +8 -0
- {vellum_ai-1.4.1.dist-info → vellum_ai-1.4.2.dist-info}/METADATA +1 -1
- {vellum_ai-1.4.1.dist-info → vellum_ai-1.4.2.dist-info}/RECORD +33 -32
- vellum_cli/tests/test_pull.py +1 -0
- vellum_cli/tests/test_push.py +2 -0
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +1 -3
- vellum_ee/workflows/display/nodes/vellum/tests/test_final_output_node.py +78 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py +5 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py +5 -0
- vellum_ee/workflows/display/types.py +3 -0
- vellum_ee/workflows/display/workflows/base_workflow_display.py +6 -0
- {vellum_ai-1.4.1.dist-info → vellum_ai-1.4.2.dist-info}/LICENSE +0 -0
- {vellum_ai-1.4.1.dist-info → vellum_ai-1.4.2.dist-info}/WHEEL +0 -0
- {vellum_ai-1.4.1.dist-info → vellum_ai-1.4.2.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.4.
|
30
|
+
"User-Agent": "vellum-ai/1.4.2",
|
31
31
|
"X-Fern-Language": "Python",
|
32
32
|
"X-Fern-SDK-Name": "vellum-ai",
|
33
|
-
"X-Fern-SDK-Version": "1.4.
|
33
|
+
"X-Fern-SDK-Version": "1.4.2",
|
34
34
|
**(self.get_custom_headers() or {}),
|
35
35
|
}
|
36
36
|
if self._api_version is not None:
|
vellum/workflows/constants.py
CHANGED
@@ -29,3 +29,11 @@ class BaseWorkflowEmitter(ABC):
|
|
29
29
|
@abstractmethod
|
30
30
|
def snapshot_state(self, state: BaseState) -> None:
|
31
31
|
pass
|
32
|
+
|
33
|
+
@abstractmethod
|
34
|
+
def join(self) -> None:
|
35
|
+
"""
|
36
|
+
Wait for any background threads or timers used by this emitter to complete.
|
37
|
+
This ensures all pending work is finished before the workflow terminates.
|
38
|
+
"""
|
39
|
+
pass
|
@@ -135,3 +135,13 @@ class VellumEmitter(BaseWorkflowEmitter):
|
|
135
135
|
request=events, # type: ignore[arg-type]
|
136
136
|
request_options=request_options,
|
137
137
|
)
|
138
|
+
|
139
|
+
def join(self) -> None:
|
140
|
+
"""
|
141
|
+
Wait for any background threads or timers used by this emitter to complete.
|
142
|
+
This ensures all pending work is finished before the workflow terminates.
|
143
|
+
"""
|
144
|
+
self._flush_events()
|
145
|
+
|
146
|
+
if self._debounce_timer and self._debounce_timer.is_alive():
|
147
|
+
self._debounce_timer.join()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from typing import Any, Dict
|
2
2
|
|
3
|
-
from pydantic import field_serializer
|
3
|
+
from pydantic import Field, field_serializer
|
4
4
|
|
5
5
|
from vellum.client.core.pydantic_utilities import UniversalBaseModel
|
6
6
|
from vellum.workflows.inputs.base import BaseInputs
|
@@ -16,7 +16,7 @@ class DatasetRow(UniversalBaseModel):
|
|
16
16
|
"""
|
17
17
|
|
18
18
|
label: str
|
19
|
-
inputs: BaseInputs
|
19
|
+
inputs: BaseInputs = Field(default_factory=BaseInputs)
|
20
20
|
|
21
21
|
@field_serializer("inputs")
|
22
22
|
def serialize_inputs(self, inputs: BaseInputs) -> Dict[str, Any]:
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from abc import ABC, ABCMeta
|
1
|
+
from abc import ABC, ABCMeta, abstractmethod
|
2
2
|
from dataclasses import field
|
3
3
|
from functools import cached_property, reduce
|
4
4
|
import inspect
|
@@ -215,6 +215,17 @@ class BaseNodeMeta(ABCMeta):
|
|
215
215
|
yield attr_value
|
216
216
|
yielded_attr_names.add(attr_name)
|
217
217
|
|
218
|
+
@abstractmethod
|
219
|
+
def __validate__(cls) -> None:
|
220
|
+
"""
|
221
|
+
Validates the node.
|
222
|
+
Subclasses can override this method to implement their specific validation logic.
|
223
|
+
Called during serialization or explicit validation.
|
224
|
+
|
225
|
+
Default implementation performs no validation.
|
226
|
+
"""
|
227
|
+
pass
|
228
|
+
|
218
229
|
|
219
230
|
class _BaseNodeTriggerMeta(type):
|
220
231
|
def __eq__(self, other: Any) -> bool:
|
@@ -112,4 +112,10 @@ class BasePromptNode(BaseNode[StateType], Generic[StateType]):
|
|
112
112
|
if not target_node_output:
|
113
113
|
return False
|
114
114
|
|
115
|
+
if not isinstance(target_node_output.instance, OutputReference):
|
116
|
+
return False
|
117
|
+
|
118
|
+
if target_node_output.instance.name != "text":
|
119
|
+
return False
|
120
|
+
|
115
121
|
return True
|
@@ -45,9 +45,15 @@ from vellum.workflows.nodes.displayable.bases.base_prompt_node import BasePrompt
|
|
45
45
|
from vellum.workflows.nodes.displayable.bases.utils import process_additional_prompt_outputs
|
46
46
|
from vellum.workflows.outputs import BaseOutput
|
47
47
|
from vellum.workflows.types import MergeBehavior
|
48
|
-
from vellum.workflows.types.definition import
|
48
|
+
from vellum.workflows.types.definition import (
|
49
|
+
ComposioToolDefinition,
|
50
|
+
DeploymentDefinition,
|
51
|
+
MCPServer,
|
52
|
+
VellumIntegrationToolDefinition,
|
53
|
+
)
|
49
54
|
from vellum.workflows.types.generics import StateType, is_workflow_class
|
50
55
|
from vellum.workflows.utils.functions import (
|
56
|
+
compile_composio_tool_definition,
|
51
57
|
compile_function_definition,
|
52
58
|
compile_inline_workflow_function_definition,
|
53
59
|
compile_mcp_tool_definition,
|
@@ -134,7 +140,7 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
|
|
134
140
|
elif isinstance(function, DeploymentDefinition):
|
135
141
|
normalized_functions.append(
|
136
142
|
compile_workflow_deployment_function_definition(
|
137
|
-
function
|
143
|
+
function,
|
138
144
|
vellum_client=self._context.vellum_client,
|
139
145
|
)
|
140
146
|
)
|
@@ -142,6 +148,14 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
|
|
142
148
|
normalized_functions.append(compile_inline_workflow_function_definition(function))
|
143
149
|
elif callable(function):
|
144
150
|
normalized_functions.append(compile_function_definition(function))
|
151
|
+
elif isinstance(function, ComposioToolDefinition):
|
152
|
+
normalized_functions.append(compile_composio_tool_definition(function))
|
153
|
+
elif isinstance(function, VellumIntegrationToolDefinition):
|
154
|
+
# TODO: Implement compile_vellum_integration_tool_definition
|
155
|
+
raise NotImplementedError(
|
156
|
+
"VellumIntegrationToolDefinition support coming soon. "
|
157
|
+
"This will be implemented when compile_vellum_integration_tool_definition is created."
|
158
|
+
)
|
145
159
|
elif isinstance(function, MCPServer):
|
146
160
|
tool_definitions = compile_mcp_tool_definition(function)
|
147
161
|
for tool_def in tool_definitions:
|
@@ -5,6 +5,7 @@ from vellum.workflows.nodes.bases import BaseNode
|
|
5
5
|
from vellum.workflows.nodes.bases.base import BaseNodeMeta
|
6
6
|
from vellum.workflows.nodes.utils import cast_to_output_type
|
7
7
|
from vellum.workflows.ports import NodePorts
|
8
|
+
from vellum.workflows.references.output import OutputReference
|
8
9
|
from vellum.workflows.types import MergeBehavior
|
9
10
|
from vellum.workflows.types.generics import StateType
|
10
11
|
from vellum.workflows.types.utils import get_original_base
|
@@ -27,6 +28,7 @@ class _FinalOutputNodeMeta(BaseNodeMeta):
|
|
27
28
|
**annotations,
|
28
29
|
"value": parent.get_output_type(),
|
29
30
|
}
|
31
|
+
|
30
32
|
return parent
|
31
33
|
|
32
34
|
def get_output_type(cls) -> Type:
|
@@ -38,6 +40,63 @@ class _FinalOutputNodeMeta(BaseNodeMeta):
|
|
38
40
|
else:
|
39
41
|
return all_args[1]
|
40
42
|
|
43
|
+
def __validate__(cls) -> None:
|
44
|
+
cls._validate_output_type_consistency(cls)
|
45
|
+
|
46
|
+
@classmethod
|
47
|
+
def _validate_output_type_consistency(mcs, cls: Type) -> None:
|
48
|
+
"""
|
49
|
+
Validates that the declared output type of FinalOutputNode matches
|
50
|
+
the type of the descriptor assigned to the 'value' attribute in its Outputs class.
|
51
|
+
|
52
|
+
Raises ValueError if there's a type mismatch.
|
53
|
+
"""
|
54
|
+
if not hasattr(cls, "Outputs"):
|
55
|
+
return
|
56
|
+
|
57
|
+
outputs_class = cls.Outputs
|
58
|
+
if not hasattr(outputs_class, "value"):
|
59
|
+
return
|
60
|
+
|
61
|
+
declared_output_type = cls.get_output_type()
|
62
|
+
value_descriptor = None
|
63
|
+
|
64
|
+
if "value" in outputs_class.__dict__:
|
65
|
+
value_descriptor = outputs_class.__dict__["value"]
|
66
|
+
else:
|
67
|
+
value_descriptor = getattr(outputs_class, "value")
|
68
|
+
|
69
|
+
if isinstance(value_descriptor, OutputReference):
|
70
|
+
descriptor_types = value_descriptor.types
|
71
|
+
|
72
|
+
type_mismatch = True
|
73
|
+
for descriptor_type in descriptor_types:
|
74
|
+
if descriptor_type == declared_output_type:
|
75
|
+
type_mismatch = False
|
76
|
+
break
|
77
|
+
try:
|
78
|
+
if issubclass(descriptor_type, declared_output_type) or issubclass(
|
79
|
+
declared_output_type, descriptor_type
|
80
|
+
):
|
81
|
+
type_mismatch = False
|
82
|
+
break
|
83
|
+
except TypeError:
|
84
|
+
# Handle cases where types aren't classes (e.g., Union)
|
85
|
+
if str(descriptor_type) == str(declared_output_type):
|
86
|
+
type_mismatch = False
|
87
|
+
break
|
88
|
+
|
89
|
+
if type_mismatch:
|
90
|
+
declared_type_name = getattr(declared_output_type, "__name__", str(declared_output_type))
|
91
|
+
descriptor_type_names = [getattr(t, "__name__", str(t)) for t in descriptor_types]
|
92
|
+
|
93
|
+
raise ValueError(
|
94
|
+
f"Output type mismatch in {cls.__name__}: "
|
95
|
+
f"FinalOutputNode is declared with output type '{declared_type_name}' "
|
96
|
+
f"but the 'value' descriptor has type(s) {descriptor_type_names}. "
|
97
|
+
f"The output descriptor type must match the declared FinalOutputNode output type."
|
98
|
+
)
|
99
|
+
|
41
100
|
|
42
101
|
class FinalOutputNode(BaseNode[StateType], Generic[StateType, _OutputType], metaclass=_FinalOutputNodeMeta):
|
43
102
|
"""
|
@@ -2,10 +2,11 @@ import pytest
|
|
2
2
|
|
3
3
|
from vellum.workflows.exceptions import NodeException
|
4
4
|
from vellum.workflows.nodes.displayable.final_output_node import FinalOutputNode
|
5
|
+
from vellum.workflows.nodes.displayable.inline_prompt_node import InlinePromptNode
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
7
8
|
|
8
|
-
def
|
9
|
+
def test_final_output_node__mismatched_output_type_should_raise_exception_when_ran():
|
9
10
|
# GIVEN a FinalOutputNode with a mismatched output type
|
10
11
|
class StringOutputNode(FinalOutputNode[BaseState, str]):
|
11
12
|
class Outputs(FinalOutputNode.Outputs):
|
@@ -18,3 +19,41 @@ def test_final_output_node__mismatched_output_type():
|
|
18
19
|
|
19
20
|
# THEN an error is raised
|
20
21
|
assert str(exc_info.value) == "Expected an output of type 'str', but received 'dict'"
|
22
|
+
|
23
|
+
|
24
|
+
def test_final_output_node__mismatched_output_type_should_raise_exception():
|
25
|
+
# GIVEN a FinalOutputNode declared with list output type but has a string value type
|
26
|
+
class Output(FinalOutputNode[BaseState, list]):
|
27
|
+
"""Output the extracted invoice line items as an array of objects."""
|
28
|
+
|
29
|
+
class Outputs(FinalOutputNode.Outputs):
|
30
|
+
value = InlinePromptNode.Outputs.text
|
31
|
+
|
32
|
+
# WHEN attempting to validate the node class
|
33
|
+
# THEN a ValueError should be raised during validation
|
34
|
+
with pytest.raises(ValueError) as exc_info:
|
35
|
+
Output.__validate__()
|
36
|
+
|
37
|
+
# AND the error message should indicate the type mismatch
|
38
|
+
assert (
|
39
|
+
str(exc_info.value)
|
40
|
+
== "Output type mismatch in Output: FinalOutputNode is declared with output type 'list' but "
|
41
|
+
"the 'value' descriptor has type(s) ['str']. The output descriptor type must match the "
|
42
|
+
"declared FinalOutputNode output type."
|
43
|
+
)
|
44
|
+
|
45
|
+
|
46
|
+
def test_final_output_node__matching_output_type_should_pass_validation():
|
47
|
+
# GIVEN a FinalOutputNode declared with correct matching types
|
48
|
+
class CorrectOutput(FinalOutputNode[BaseState, str]):
|
49
|
+
"""Output with correct type matching."""
|
50
|
+
|
51
|
+
class Outputs(FinalOutputNode.Outputs):
|
52
|
+
value = InlinePromptNode.Outputs.text
|
53
|
+
|
54
|
+
# WHEN attempting to validate the node class
|
55
|
+
# THEN validation should pass without raising an exception
|
56
|
+
try:
|
57
|
+
CorrectOutput.__validate__()
|
58
|
+
except ValueError:
|
59
|
+
pytest.fail("Validation should not raise an exception for correct type matching")
|
@@ -2,6 +2,7 @@ from typing import Any, ClassVar, Dict, Generic, Iterator, List, Optional, Set,
|
|
2
2
|
|
3
3
|
from vellum import ChatMessage, PromptBlock
|
4
4
|
from vellum.client.types.prompt_parameters import PromptParameters
|
5
|
+
from vellum.client.types.prompt_settings import PromptSettings
|
5
6
|
from vellum.prompts.constants import DEFAULT_PROMPT_PARAMETERS
|
6
7
|
from vellum.workflows.context import execution_context, get_parent_context
|
7
8
|
from vellum.workflows.errors.types import WorkflowErrorCode
|
@@ -47,6 +48,7 @@ class ToolCallingNode(BaseNode[StateType], Generic[StateType]):
|
|
47
48
|
prompt_inputs: ClassVar[Optional[EntityInputsInterface]] = None
|
48
49
|
parameters: PromptParameters = DEFAULT_PROMPT_PARAMETERS
|
49
50
|
max_prompt_iterations: ClassVar[Optional[int]] = 5
|
51
|
+
settings: ClassVar[Optional[Union[PromptSettings, Dict[str, Any]]]] = None
|
50
52
|
|
51
53
|
class Outputs(BaseOutputs):
|
52
54
|
"""
|
@@ -150,6 +152,7 @@ class ToolCallingNode(BaseNode[StateType], Generic[StateType]):
|
|
150
152
|
max_prompt_iterations=self.max_prompt_iterations,
|
151
153
|
process_parameters_method=process_parameters_method,
|
152
154
|
process_blocks_method=process_blocks_method,
|
155
|
+
settings=self.settings,
|
153
156
|
)
|
154
157
|
|
155
158
|
# Create the router node (handles routing logic only)
|
@@ -5,6 +5,7 @@ from vellum.client.types.chat_message_prompt_block import ChatMessagePromptBlock
|
|
5
5
|
from vellum.client.types.fulfilled_execute_prompt_event import FulfilledExecutePromptEvent
|
6
6
|
from vellum.client.types.initiated_execute_prompt_event import InitiatedExecutePromptEvent
|
7
7
|
from vellum.client.types.plain_text_prompt_block import PlainTextPromptBlock
|
8
|
+
from vellum.client.types.prompt_settings import PromptSettings
|
8
9
|
from vellum.client.types.rich_text_prompt_block import RichTextPromptBlock
|
9
10
|
from vellum.client.types.string_vellum_value import StringVellumValue
|
10
11
|
from vellum.client.types.variable_prompt_block import VariablePromptBlock
|
@@ -250,3 +251,66 @@ def test_get_mcp_tool_name_snake_case():
|
|
250
251
|
|
251
252
|
result = get_mcp_tool_name(mcp_tool)
|
252
253
|
assert result == "github_server__create_repository"
|
254
|
+
|
255
|
+
|
256
|
+
def test_create_tool_prompt_node_settings_dict_stream_disabled(vellum_adhoc_prompt_client):
|
257
|
+
# GIVEN settings provided as dict with stream disabled
|
258
|
+
tool_prompt_node = create_tool_prompt_node(
|
259
|
+
ml_model="gpt-4o-mini",
|
260
|
+
blocks=[],
|
261
|
+
functions=[],
|
262
|
+
prompt_inputs=None,
|
263
|
+
parameters=DEFAULT_PROMPT_PARAMETERS,
|
264
|
+
max_prompt_iterations=1,
|
265
|
+
settings={"stream_enabled": False},
|
266
|
+
)
|
267
|
+
|
268
|
+
# AND the API mocks
|
269
|
+
def generate_non_stream_response(*args, **kwargs):
|
270
|
+
return FulfilledExecutePromptEvent(execution_id=str(uuid4()), outputs=[StringVellumValue(value="ok")])
|
271
|
+
|
272
|
+
vellum_adhoc_prompt_client.adhoc_execute_prompt.side_effect = generate_non_stream_response
|
273
|
+
|
274
|
+
# WHEN we run the node
|
275
|
+
node_instance = tool_prompt_node()
|
276
|
+
list(node_instance.run())
|
277
|
+
|
278
|
+
# THEN the node should have called the API correctly
|
279
|
+
assert node_instance.settings is not None
|
280
|
+
assert node_instance.settings.stream_enabled is False
|
281
|
+
assert vellum_adhoc_prompt_client.adhoc_execute_prompt.call_count == 1
|
282
|
+
assert vellum_adhoc_prompt_client.adhoc_execute_prompt_stream.call_count == 0
|
283
|
+
|
284
|
+
|
285
|
+
def test_create_tool_prompt_node_settings_model_stream_enabled(vellum_adhoc_prompt_client):
|
286
|
+
# GIVEN settings provided as PromptSettings with stream enabled
|
287
|
+
tool_prompt_node = create_tool_prompt_node(
|
288
|
+
ml_model="gpt-4o-mini",
|
289
|
+
blocks=[],
|
290
|
+
functions=[],
|
291
|
+
prompt_inputs=None,
|
292
|
+
parameters=DEFAULT_PROMPT_PARAMETERS,
|
293
|
+
max_prompt_iterations=1,
|
294
|
+
settings=PromptSettings(stream_enabled=True),
|
295
|
+
)
|
296
|
+
|
297
|
+
# AND the API mocks
|
298
|
+
def generate_stream_events(*args, **kwargs):
|
299
|
+
execution_id = str(uuid4())
|
300
|
+
events = [
|
301
|
+
InitiatedExecutePromptEvent(execution_id=execution_id),
|
302
|
+
FulfilledExecutePromptEvent(execution_id=execution_id, outputs=[StringVellumValue(value="ok")]),
|
303
|
+
]
|
304
|
+
yield from events
|
305
|
+
|
306
|
+
vellum_adhoc_prompt_client.adhoc_execute_prompt_stream.side_effect = generate_stream_events
|
307
|
+
|
308
|
+
# WHEN we run the node
|
309
|
+
node_instance = tool_prompt_node()
|
310
|
+
list(node_instance.run())
|
311
|
+
|
312
|
+
# THEN the node should have called the API correctly
|
313
|
+
assert node_instance.settings is not None
|
314
|
+
assert node_instance.settings.stream_enabled is True
|
315
|
+
assert vellum_adhoc_prompt_client.adhoc_execute_prompt_stream.call_count == 1
|
316
|
+
assert vellum_adhoc_prompt_client.adhoc_execute_prompt.call_count == 0
|
@@ -9,9 +9,9 @@ from vellum.client.types.array_chat_message_content import ArrayChatMessageConte
|
|
9
9
|
from vellum.client.types.array_chat_message_content_item import ArrayChatMessageContentItem
|
10
10
|
from vellum.client.types.function_call_chat_message_content import FunctionCallChatMessageContent
|
11
11
|
from vellum.client.types.function_call_chat_message_content_value import FunctionCallChatMessageContentValue
|
12
|
-
from vellum.client.types.function_definition import FunctionDefinition
|
13
12
|
from vellum.client.types.prompt_output import PromptOutput
|
14
13
|
from vellum.client.types.prompt_parameters import PromptParameters
|
14
|
+
from vellum.client.types.prompt_settings import PromptSettings
|
15
15
|
from vellum.client.types.string_chat_message_content import StringChatMessageContent
|
16
16
|
from vellum.client.types.variable_prompt_block import VariablePromptBlock
|
17
17
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
@@ -31,7 +31,13 @@ from vellum.workflows.ports.port import Port
|
|
31
31
|
from vellum.workflows.state import BaseState
|
32
32
|
from vellum.workflows.state.encoder import DefaultStateEncoder
|
33
33
|
from vellum.workflows.types.core import EntityInputsInterface, MergeBehavior, Tool, ToolBase
|
34
|
-
from vellum.workflows.types.definition import
|
34
|
+
from vellum.workflows.types.definition import (
|
35
|
+
ComposioToolDefinition,
|
36
|
+
DeploymentDefinition,
|
37
|
+
MCPServer,
|
38
|
+
MCPToolDefinition,
|
39
|
+
VellumIntegrationToolDefinition,
|
40
|
+
)
|
35
41
|
from vellum.workflows.types.generics import is_workflow_class
|
36
42
|
from vellum.workflows.utils.functions import compile_mcp_tool_definition, get_mcp_tool_name
|
37
43
|
|
@@ -274,36 +280,6 @@ class ElseNode(BaseNode[ToolCallingState]):
|
|
274
280
|
return self.Outputs()
|
275
281
|
|
276
282
|
|
277
|
-
def _hydrate_composio_tool_definition(tool_def: ComposioToolDefinition) -> FunctionDefinition:
|
278
|
-
"""Hydrate a ComposioToolDefinition with detailed information from the Composio API.
|
279
|
-
|
280
|
-
Args:
|
281
|
-
tool_def: The basic ComposioToolDefinition to enhance
|
282
|
-
|
283
|
-
Returns:
|
284
|
-
FunctionDefinition with detailed parameters and description
|
285
|
-
"""
|
286
|
-
try:
|
287
|
-
composio_service = ComposioService()
|
288
|
-
tool_details = composio_service.get_tool_by_slug(tool_def.action)
|
289
|
-
|
290
|
-
# Create a FunctionDefinition directly with proper field extraction
|
291
|
-
return FunctionDefinition(
|
292
|
-
name=tool_def.name,
|
293
|
-
description=tool_details.get("description", tool_def.description),
|
294
|
-
parameters=tool_details.get("input_parameters", {}),
|
295
|
-
)
|
296
|
-
|
297
|
-
except Exception as e:
|
298
|
-
# If hydration fails (including no API key), log and return basic function definition
|
299
|
-
logger.warning(f"Failed to enhance Composio tool '{tool_def.action}': {e}")
|
300
|
-
return FunctionDefinition(
|
301
|
-
name=tool_def.name,
|
302
|
-
description=tool_def.description,
|
303
|
-
parameters={},
|
304
|
-
)
|
305
|
-
|
306
|
-
|
307
283
|
def create_tool_prompt_node(
|
308
284
|
ml_model: str,
|
309
285
|
blocks: List[Union[PromptBlock, Dict[str, Any]]],
|
@@ -313,17 +289,10 @@ def create_tool_prompt_node(
|
|
313
289
|
max_prompt_iterations: Optional[int] = None,
|
314
290
|
process_parameters_method: Optional[Callable] = None,
|
315
291
|
process_blocks_method: Optional[Callable] = None,
|
292
|
+
settings: Optional[Union[PromptSettings, Dict[str, Any]]] = None,
|
316
293
|
) -> Type[ToolPromptNode]:
|
317
294
|
if functions and len(functions) > 0:
|
318
|
-
prompt_functions: List[
|
319
|
-
|
320
|
-
for function in functions:
|
321
|
-
if isinstance(function, ComposioToolDefinition):
|
322
|
-
# Get Composio tool details and hydrate the function definition
|
323
|
-
enhanced_function = _hydrate_composio_tool_definition(function)
|
324
|
-
prompt_functions.append(enhanced_function)
|
325
|
-
else:
|
326
|
-
prompt_functions.append(function)
|
295
|
+
prompt_functions: List[Tool] = functions
|
327
296
|
else:
|
328
297
|
prompt_functions = []
|
329
298
|
|
@@ -359,6 +328,13 @@ def create_tool_prompt_node(
|
|
359
328
|
),
|
360
329
|
}
|
361
330
|
|
331
|
+
# Normalize settings to PromptSettings if provided as a dict
|
332
|
+
normalized_settings: Optional[PromptSettings]
|
333
|
+
if isinstance(settings, dict):
|
334
|
+
normalized_settings = PromptSettings.model_validate(settings)
|
335
|
+
else:
|
336
|
+
normalized_settings = settings
|
337
|
+
|
362
338
|
node = cast(
|
363
339
|
Type[ToolPromptNode],
|
364
340
|
type(
|
@@ -371,6 +347,7 @@ def create_tool_prompt_node(
|
|
371
347
|
"prompt_inputs": node_prompt_inputs,
|
372
348
|
"parameters": parameters,
|
373
349
|
"max_prompt_iterations": max_prompt_iterations,
|
350
|
+
"settings": normalized_settings,
|
374
351
|
**({"process_parameters": process_parameters_method} if process_parameters_method is not None else {}),
|
375
352
|
**({"process_blocks": process_blocks_method} if process_blocks_method is not None else {}),
|
376
353
|
"__module__": __name__,
|
@@ -409,6 +386,10 @@ def create_router_node(
|
|
409
386
|
function_name = get_function_name(function)
|
410
387
|
port = create_port_condition(function_name)
|
411
388
|
setattr(Ports, function_name, port)
|
389
|
+
elif isinstance(function, VellumIntegrationToolDefinition):
|
390
|
+
function_name = get_function_name(function)
|
391
|
+
port = create_port_condition(function_name)
|
392
|
+
setattr(Ports, function_name, port)
|
412
393
|
elif isinstance(function, MCPServer):
|
413
394
|
tool_functions: List[MCPToolDefinition] = compile_mcp_tool_definition(function)
|
414
395
|
for tool_function in tool_functions:
|
@@ -483,6 +464,12 @@ def create_function_node(
|
|
483
464
|
},
|
484
465
|
)
|
485
466
|
return node
|
467
|
+
elif isinstance(function, VellumIntegrationToolDefinition):
|
468
|
+
# TODO: Implement VellumIntegrationNode
|
469
|
+
raise NotImplementedError(
|
470
|
+
"VellumIntegrationToolDefinition support coming soon. "
|
471
|
+
"This will be implemented when the VellumIntegrationService is created."
|
472
|
+
)
|
486
473
|
elif is_workflow_class(function):
|
487
474
|
function.is_dynamic = True
|
488
475
|
node = type(
|
@@ -572,5 +559,7 @@ def get_function_name(function: ToolBase) -> str:
|
|
572
559
|
elif isinstance(function, ComposioToolDefinition):
|
573
560
|
# model post init sets the name to the action if it's not set
|
574
561
|
return function.name # type: ignore[return-value]
|
562
|
+
elif isinstance(function, VellumIntegrationToolDefinition):
|
563
|
+
return function.name
|
575
564
|
else:
|
576
565
|
return snake_case(function.__name__)
|
@@ -97,3 +97,32 @@ def test_dataset_row_with_default_inputs():
|
|
97
97
|
assert serialized_dict["label"] == "defaults_test"
|
98
98
|
assert serialized_dict["inputs"]["required_field"] == "required_value"
|
99
99
|
assert serialized_dict["inputs"]["optional_with_default"] == "default_value"
|
100
|
+
|
101
|
+
|
102
|
+
def test_dataset_row_without_inputs():
|
103
|
+
"""
|
104
|
+
Test that DatasetRow can be created with only a label (no inputs parameter).
|
105
|
+
"""
|
106
|
+
|
107
|
+
dataset_row = DatasetRow(label="test_label_only")
|
108
|
+
|
109
|
+
serialized_dict = dataset_row.model_dump()
|
110
|
+
|
111
|
+
assert serialized_dict["label"] == "test_label_only"
|
112
|
+
assert serialized_dict["inputs"] == {}
|
113
|
+
|
114
|
+
assert isinstance(dataset_row.inputs, BaseInputs)
|
115
|
+
|
116
|
+
|
117
|
+
def test_dataset_row_with_empty_inputs():
|
118
|
+
"""
|
119
|
+
Test that DatasetRow can be created with explicitly empty BaseInputs.
|
120
|
+
"""
|
121
|
+
|
122
|
+
# GIVEN a DatasetRow with explicitly empty BaseInputs
|
123
|
+
dataset_row = DatasetRow(label="test_label", inputs=BaseInputs())
|
124
|
+
|
125
|
+
serialized_dict = dataset_row.model_dump()
|
126
|
+
|
127
|
+
assert serialized_dict["label"] == "test_label"
|
128
|
+
assert serialized_dict["inputs"] == {}
|
vellum/workflows/types/core.py
CHANGED
@@ -13,7 +13,12 @@ from typing import ( # type: ignore[attr-defined]
|
|
13
13
|
)
|
14
14
|
|
15
15
|
from vellum.client.core.pydantic_utilities import UniversalBaseModel
|
16
|
-
from vellum.workflows.types.definition import
|
16
|
+
from vellum.workflows.types.definition import (
|
17
|
+
ComposioToolDefinition,
|
18
|
+
DeploymentDefinition,
|
19
|
+
MCPServer,
|
20
|
+
VellumIntegrationToolDefinition,
|
21
|
+
)
|
17
22
|
|
18
23
|
if TYPE_CHECKING:
|
19
24
|
from vellum.workflows.workflows.base import BaseWorkflow
|
@@ -51,5 +56,11 @@ class ConditionType(Enum):
|
|
51
56
|
|
52
57
|
|
53
58
|
# Type alias for functions that can be called in tool calling nodes
|
54
|
-
ToolBase = Union[
|
59
|
+
ToolBase = Union[
|
60
|
+
Callable[..., Any],
|
61
|
+
DeploymentDefinition,
|
62
|
+
Type["BaseWorkflow"],
|
63
|
+
ComposioToolDefinition,
|
64
|
+
VellumIntegrationToolDefinition,
|
65
|
+
]
|
55
66
|
Tool = Union[ToolBase, MCPServer]
|
@@ -10,7 +10,7 @@ from vellum import Vellum
|
|
10
10
|
from vellum.client.core.pydantic_utilities import UniversalBaseModel
|
11
11
|
from vellum.client.types.code_resource_definition import CodeResourceDefinition as ClientCodeResourceDefinition
|
12
12
|
from vellum.client.types.vellum_variable import VellumVariable
|
13
|
-
from vellum.workflows.constants import AuthorizationType
|
13
|
+
from vellum.workflows.constants import AuthorizationType, VellumIntegrationProviderType
|
14
14
|
from vellum.workflows.references.environment_variable import EnvironmentVariableReference
|
15
15
|
|
16
16
|
|
@@ -165,6 +165,18 @@ class ComposioToolDefinition(UniversalBaseModel):
|
|
165
165
|
self.name = self.action.lower()
|
166
166
|
|
167
167
|
|
168
|
+
class VellumIntegrationToolDefinition(UniversalBaseModel):
|
169
|
+
type: Literal["INTEGRATION"] = "INTEGRATION"
|
170
|
+
|
171
|
+
# Core identification
|
172
|
+
provider: VellumIntegrationProviderType
|
173
|
+
integration: str # "GITHUB", "SLACK", etc.
|
174
|
+
name: str # Specific action like "GITHUB_CREATE_AN_ISSUE"
|
175
|
+
|
176
|
+
# Required for tool base consistency
|
177
|
+
description: str
|
178
|
+
|
179
|
+
|
168
180
|
class MCPServer(UniversalBaseModel):
|
169
181
|
type: Literal["MCP_SERVER"] = "MCP_SERVER"
|
170
182
|
name: str
|
@@ -1,19 +1,6 @@
|
|
1
1
|
import dataclasses
|
2
2
|
import inspect
|
3
|
-
from typing import
|
4
|
-
TYPE_CHECKING,
|
5
|
-
Annotated,
|
6
|
-
Any,
|
7
|
-
Callable,
|
8
|
-
Dict,
|
9
|
-
List,
|
10
|
-
Literal,
|
11
|
-
Optional,
|
12
|
-
Type,
|
13
|
-
Union,
|
14
|
-
get_args,
|
15
|
-
get_origin,
|
16
|
-
)
|
3
|
+
from typing import TYPE_CHECKING, Annotated, Any, Callable, List, Literal, Optional, Type, Union, get_args, get_origin
|
17
4
|
|
18
5
|
from pydantic import BaseModel
|
19
6
|
from pydantic_core import PydanticUndefined
|
@@ -21,8 +8,15 @@ from pydash import snake_case
|
|
21
8
|
|
22
9
|
from vellum import Vellum
|
23
10
|
from vellum.client.types.function_definition import FunctionDefinition
|
11
|
+
from vellum.workflows.integrations.composio_service import ComposioService
|
24
12
|
from vellum.workflows.integrations.mcp_service import MCPService
|
25
|
-
from vellum.workflows.types.definition import
|
13
|
+
from vellum.workflows.types.definition import (
|
14
|
+
ComposioToolDefinition,
|
15
|
+
DeploymentDefinition,
|
16
|
+
MCPServer,
|
17
|
+
MCPToolDefinition,
|
18
|
+
VellumIntegrationToolDefinition,
|
19
|
+
)
|
26
20
|
from vellum.workflows.utils.vellum_variables import vellum_variable_type_to_openapi_type
|
27
21
|
|
28
22
|
if TYPE_CHECKING:
|
@@ -238,25 +232,21 @@ def compile_inline_workflow_function_definition(workflow_class: Type["BaseWorkfl
|
|
238
232
|
|
239
233
|
|
240
234
|
def compile_workflow_deployment_function_definition(
|
241
|
-
|
235
|
+
deployment_definition: DeploymentDefinition,
|
242
236
|
vellum_client: Vellum,
|
243
237
|
) -> FunctionDefinition:
|
244
238
|
"""
|
245
239
|
Converts a deployment workflow config into our Vellum-native FunctionDefinition type.
|
246
240
|
|
247
241
|
Args:
|
248
|
-
|
242
|
+
deployment_definition: DeploymentDefinition instance
|
249
243
|
vellum_client: Vellum client instance
|
250
244
|
"""
|
251
|
-
|
252
|
-
release_tag = deployment_config["release_tag"]
|
253
|
-
|
254
|
-
workflow_deployment_release = vellum_client.workflow_deployments.retrieve_workflow_deployment_release(
|
255
|
-
deployment, release_tag
|
256
|
-
)
|
245
|
+
release_info = deployment_definition.get_release_info(vellum_client)
|
257
246
|
|
258
|
-
|
259
|
-
description =
|
247
|
+
name = release_info["name"]
|
248
|
+
description = release_info["description"]
|
249
|
+
input_variables = release_info["input_variables"]
|
260
250
|
|
261
251
|
properties = {}
|
262
252
|
required = []
|
@@ -270,7 +260,7 @@ def compile_workflow_deployment_function_definition(
|
|
270
260
|
parameters = {"type": "object", "properties": properties, "required": required}
|
271
261
|
|
272
262
|
return FunctionDefinition(
|
273
|
-
name=
|
263
|
+
name=name.replace("-", ""),
|
274
264
|
description=description,
|
275
265
|
parameters=parameters,
|
276
266
|
)
|
@@ -300,6 +290,53 @@ def compile_mcp_tool_definition(server_def: MCPServer) -> List[MCPToolDefinition
|
|
300
290
|
return []
|
301
291
|
|
302
292
|
|
293
|
+
def compile_composio_tool_definition(tool_def: ComposioToolDefinition) -> FunctionDefinition:
|
294
|
+
"""Hydrate a ComposioToolDefinition with detailed information from the Composio API.
|
295
|
+
|
296
|
+
Args:
|
297
|
+
tool_def: The basic ComposioToolDefinition to enhance
|
298
|
+
|
299
|
+
Returns:
|
300
|
+
FunctionDefinition with detailed parameters and description
|
301
|
+
"""
|
302
|
+
try:
|
303
|
+
composio_service = ComposioService()
|
304
|
+
tool_details = composio_service.get_tool_by_slug(tool_def.action)
|
305
|
+
|
306
|
+
# Create a FunctionDefinition directly with proper field extraction
|
307
|
+
return FunctionDefinition(
|
308
|
+
name=tool_def.name,
|
309
|
+
description=tool_details.get("description", tool_def.description),
|
310
|
+
parameters=tool_details.get("input_parameters", {}),
|
311
|
+
)
|
312
|
+
except Exception:
|
313
|
+
# If hydration fails (including no API key), return basic function definition
|
314
|
+
return FunctionDefinition(
|
315
|
+
name=tool_def.name,
|
316
|
+
description=tool_def.description,
|
317
|
+
parameters={},
|
318
|
+
)
|
319
|
+
|
320
|
+
|
321
|
+
def compile_vellum_integration_tool_definition(tool_def: VellumIntegrationToolDefinition) -> FunctionDefinition:
|
322
|
+
"""Compile a VellumIntegrationToolDefinition into a FunctionDefinition.
|
323
|
+
|
324
|
+
TODO: Implement when VellumIntegrationService is created.
|
325
|
+
|
326
|
+
Args:
|
327
|
+
tool_def: The VellumIntegrationToolDefinition to compile
|
328
|
+
|
329
|
+
Returns:
|
330
|
+
FunctionDefinition with tool parameters and description
|
331
|
+
"""
|
332
|
+
# TODO: Implement when VellumIntegrationService is available
|
333
|
+
# This will eventually use VellumIntegrationService to fetch tool details
|
334
|
+
raise NotImplementedError(
|
335
|
+
"VellumIntegrationToolDefinition compilation coming soon. "
|
336
|
+
"This will be implemented when the VellumIntegrationService is created."
|
337
|
+
)
|
338
|
+
|
339
|
+
|
303
340
|
def use_tool_inputs(**inputs):
|
304
341
|
"""
|
305
342
|
Decorator to specify which parameters of a tool function should be provided
|
@@ -13,6 +13,7 @@ from vellum.workflows import BaseWorkflow
|
|
13
13
|
from vellum.workflows.inputs.base import BaseInputs
|
14
14
|
from vellum.workflows.nodes.bases.base import BaseNode
|
15
15
|
from vellum.workflows.state.base import BaseState
|
16
|
+
from vellum.workflows.types.definition import DeploymentDefinition
|
16
17
|
from vellum.workflows.utils.functions import (
|
17
18
|
compile_function_definition,
|
18
19
|
compile_inline_workflow_function_definition,
|
@@ -449,14 +450,15 @@ def test_compile_workflow_deployment_function_definition__just_name():
|
|
449
450
|
# GIVEN a mock Vellum client and deployment
|
450
451
|
mock_client = Mock()
|
451
452
|
mock_release = Mock()
|
453
|
+
mock_release.deployment.name = "my_deployment"
|
452
454
|
mock_release.workflow_version.input_variables = []
|
453
455
|
mock_release.description = "This is a test deployment"
|
454
456
|
mock_client.workflow_deployments.retrieve_workflow_deployment_release.return_value = mock_release
|
455
457
|
|
456
|
-
|
458
|
+
deployment_definition = DeploymentDefinition(deployment="my_deployment", release_tag="LATEST")
|
457
459
|
|
458
460
|
# WHEN compiling the deployment workflow function
|
459
|
-
compiled_function = compile_workflow_deployment_function_definition(
|
461
|
+
compiled_function = compile_workflow_deployment_function_definition(deployment_definition, mock_client)
|
460
462
|
|
461
463
|
# THEN it should return the compiled function definition (same structure as function test)
|
462
464
|
assert compiled_function == FunctionDefinition(
|
@@ -496,13 +498,14 @@ def test_compile_workflow_deployment_function_definition__all_args():
|
|
496
498
|
mock_inputs.append(mock_input)
|
497
499
|
|
498
500
|
mock_release.workflow_version.input_variables = mock_inputs
|
501
|
+
mock_release.deployment.name = "my_deployment"
|
499
502
|
mock_release.description = "This is a test deployment"
|
500
503
|
mock_client.workflow_deployments.retrieve_workflow_deployment_release.return_value = mock_release
|
501
504
|
|
502
|
-
|
505
|
+
deployment_definition = DeploymentDefinition(deployment="my_deployment", release_tag="latest")
|
503
506
|
|
504
507
|
# WHEN compiling the deployment workflow function
|
505
|
-
compiled_function = compile_workflow_deployment_function_definition(
|
508
|
+
compiled_function = compile_workflow_deployment_function_definition(deployment_definition, mock_client)
|
506
509
|
|
507
510
|
# THEN it should return the compiled function definition
|
508
511
|
assert compiled_function == FunctionDefinition(
|
@@ -564,13 +567,14 @@ def test_compile_workflow_deployment_function_definition__defaults():
|
|
564
567
|
mock_inputs.append(mock_input_actual_default)
|
565
568
|
|
566
569
|
mock_release.workflow_version.input_variables = mock_inputs
|
570
|
+
mock_release.deployment.name = "my_deployment"
|
567
571
|
mock_release.description = "This is a test deployment"
|
568
572
|
mock_client.workflow_deployments.retrieve_workflow_deployment_release.return_value = mock_release
|
569
573
|
|
570
|
-
|
574
|
+
deployment_definition = DeploymentDefinition(deployment="my_deployment", release_tag="LATEST")
|
571
575
|
|
572
576
|
# WHEN compiling the deployment workflow function
|
573
|
-
compiled_function = compile_workflow_deployment_function_definition(
|
577
|
+
compiled_function = compile_workflow_deployment_function_definition(deployment_definition, mock_client)
|
574
578
|
|
575
579
|
# THEN it should return the compiled function definition with proper default handling
|
576
580
|
assert compiled_function == FunctionDefinition(
|
@@ -2,15 +2,21 @@ import os
|
|
2
2
|
from typing import List, Optional
|
3
3
|
|
4
4
|
from vellum import Vellum, VellumEnvironment
|
5
|
+
from vellum.client.types.api_version_enum import ApiVersionEnum
|
5
6
|
|
6
7
|
|
7
|
-
def create_vellum_client(
|
8
|
+
def create_vellum_client(
|
9
|
+
api_key: Optional[str] = None,
|
10
|
+
api_url: Optional[str] = None,
|
11
|
+
api_version: Optional[ApiVersionEnum] = None,
|
12
|
+
) -> Vellum:
|
8
13
|
if api_key is None:
|
9
14
|
api_key = os.getenv("VELLUM_API_KEY", default="")
|
10
15
|
|
11
16
|
return Vellum(
|
12
17
|
api_key=api_key,
|
13
18
|
environment=create_vellum_environment(api_url),
|
19
|
+
api_version=api_version,
|
14
20
|
)
|
15
21
|
|
16
22
|
|
@@ -687,6 +687,14 @@ class BaseWorkflow(Generic[InputsType, StateType], BaseExecutable, metaclass=_Ba
|
|
687
687
|
raise ValueError(f"Multiple workflows found in {module_path}")
|
688
688
|
return workflows[0]
|
689
689
|
|
690
|
+
def join(self) -> None:
|
691
|
+
"""
|
692
|
+
Wait for all emitters to complete their background work.
|
693
|
+
This ensures all pending events are processed before the workflow terminates.
|
694
|
+
"""
|
695
|
+
for emitter in self.emitters:
|
696
|
+
emitter.join()
|
697
|
+
|
690
698
|
|
691
699
|
WorkflowExecutionInitiatedBody.model_rebuild()
|
692
700
|
WorkflowExecutionFulfilledBody.model_rebuild()
|
@@ -19,8 +19,8 @@ vellum_cli/tests/test_init.py,sha256=C_rV4lu-ab5iFoLRizs1XAUnSPdMf7oFuc1i4N4udOU
|
|
19
19
|
vellum_cli/tests/test_main.py,sha256=qDZG-aQauPwBwM6A2DIu1494n47v3pL28XakTbLGZ-k,272
|
20
20
|
vellum_cli/tests/test_move.py,sha256=FIrL1xlH5oFKGX2MugcTKL8JilpopmUC7hP5OaqF5zw,5213
|
21
21
|
vellum_cli/tests/test_ping.py,sha256=b3aQLd-N59_8w2rRiWqwpB1rlHaKEYVbAj1Y3hi7A-g,2605
|
22
|
-
vellum_cli/tests/test_pull.py,sha256=
|
23
|
-
vellum_cli/tests/test_push.py,sha256=
|
22
|
+
vellum_cli/tests/test_pull.py,sha256=e2XHzcHIx9k-FyuNAl7wMSNsSSebPGyP6U05JGcddFs,49447
|
23
|
+
vellum_cli/tests/test_push.py,sha256=2MjkNKr_9Guv5Exjsm3L1BeVXmPkKUcCSiKnp90HgW4,41996
|
24
24
|
vellum_ee/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
25
|
vellum_ee/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
26
26
|
vellum_ee/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -44,7 +44,7 @@ vellum_ee/workflows/display/nodes/vellum/conditional_node.py,sha256=dtO9A-rjbDEJ
|
|
44
44
|
vellum_ee/workflows/display/nodes/vellum/error_node.py,sha256=8tSb8qGVoRIELubu0qPeoDlt1LpiIqc6d9_30GWRd_k,2266
|
45
45
|
vellum_ee/workflows/display/nodes/vellum/final_output_node.py,sha256=z4oeTgKnMGVaGig8XOZm5B_xYL4H7zweYlFweCbhnyA,3000
|
46
46
|
vellum_ee/workflows/display/nodes/vellum/guardrail_node.py,sha256=9_AslWjzj4RHH2sq3SIaq9FU0NCg7ex5TIWrNMybqXg,2173
|
47
|
-
vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=
|
47
|
+
vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=muyLv3KMIsUnnXhiPbPhw5B0TO1Z8LUwytpVQKlz4tM,11906
|
48
48
|
vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py,sha256=qy_EtBIAHIhju68PA-skm-WbFnaNEuDoxkSMWRl2SpQ,5870
|
49
49
|
vellum_ee/workflows/display/nodes/vellum/map_node.py,sha256=kwLqptup7bzYUDkGDbpcJPMMusMezsYrG5rSUYl5TlQ,3750
|
50
50
|
vellum_ee/workflows/display/nodes/vellum/merge_node.py,sha256=xMHaPfTSZWYprQenlHm2g47u0a5O9Me_dhAjfqo8nKQ,3116
|
@@ -58,6 +58,7 @@ vellum_ee/workflows/display/nodes/vellum/tests/__init__.py,sha256=47DEQpj8HBSa-_
|
|
58
58
|
vellum_ee/workflows/display/nodes/vellum/tests/test_api_node.py,sha256=DQAtsabvn6BE6xWwKNHzMOppzoy1-1dssNnrwbHUdRU,1490
|
59
59
|
vellum_ee/workflows/display/nodes/vellum/tests/test_code_execution_node.py,sha256=oEH9myRn-NAP_mRstV0LifX3ncbmAOjCvyIVCZhACk0,10885
|
60
60
|
vellum_ee/workflows/display/nodes/vellum/tests/test_error_node.py,sha256=540FoWMpJ3EN_DPjHsr9ODJWCRVcUa5hZBn-5T2GiHU,1665
|
61
|
+
vellum_ee/workflows/display/nodes/vellum/tests/test_final_output_node.py,sha256=KVftEQxXARlcr-Uuo1ZK_wEHTcTH64OZJ3Ub3mN8x7I,3006
|
61
62
|
vellum_ee/workflows/display/nodes/vellum/tests/test_inline_subworkflow_node.py,sha256=SKOYan-dxY4gsO0R4JyQUyWrABHBN8XImKw9Eeo4wGo,3535
|
62
63
|
vellum_ee/workflows/display/nodes/vellum/tests/test_note_node.py,sha256=uiMB0cOxKZzos7YKnj4ef4DFa2bOvZJWIv-hfbUV6Go,1218
|
63
64
|
vellum_ee/workflows/display/nodes/vellum/tests/test_prompt_deployment_node.py,sha256=54oatuBB98Dfbr08NqZU8ZNhfQdJWhODIwjsegPPJJw,6376
|
@@ -98,17 +99,17 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_
|
|
98
99
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py,sha256=ddPa8gNBYH2tWk92ymngY7M8n74J-8CEre50HISP_-g,7877
|
99
100
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py,sha256=A7Ef8P1-Nyvsb97bumKT9W2R1LuZaY9IKFV-7iRueog,4010
|
100
101
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_composio_serialization.py,sha256=oVXCjkU0G56QJmqnd_xIwF3D9bhJwALFibM2wmRhwUk,3739
|
101
|
-
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py,sha256=
|
102
|
+
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py,sha256=K7r5hivC3-599oqbkLgj5WMBcrix1znmuhAxs0w0EAE,26692
|
102
103
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_mcp_serialization.py,sha256=QhQbijeCnFeX1i3SMjHJg2WVAEt5JEO3dhFRv-mofdA,2458
|
103
104
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_parent_input.py,sha256=__LX4cuzbyZp_1wc-SI8X_J0tnhOkCEmRVUWLKI5aQM,4578
|
104
|
-
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py,sha256=
|
105
|
+
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py,sha256=5yaoN5aM6VZZtsleQcSWpbNyWLE1nTnMF6KbLmCrlc8,10437
|
105
106
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_workflow_deployment_serialization.py,sha256=XIZZr5POo2NLn2uEWm9EC3rejeBMoO4X-JtzTH6mvp4,4074
|
106
107
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py,sha256=pLCyMScV88DTBXRH7jXaXOEA1GBq8NIipCUFwIAWnwI,2771
|
107
108
|
vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py,sha256=exT7U-axwtYgFylagScflSQLJEND51qIAx2UATju6JM,6023
|
108
109
|
vellum_ee/workflows/display/tests/workflow_serialization/test_final_output_node_map_reference_serialization.py,sha256=vl3pxUJlrYRA8zzFJ-gRm7fe-5fviLNSIsUC7imnMqk,3502
|
109
110
|
vellum_ee/workflows/display/tests/workflow_serialization/test_web_search_node_serialization.py,sha256=vbDFBrWUPeeW7cxjNA6SXrsHlYcbOAhlQ4C45Vdnr1c,3428
|
110
111
|
vellum_ee/workflows/display/tests/workflow_serialization/test_workflow_input_parameterization_error.py,sha256=vAdmn3YTBDpo55znbydQxsgg9ASqHcvsUPwiBR_7wfo,1461
|
111
|
-
vellum_ee/workflows/display/types.py,sha256=
|
112
|
+
vellum_ee/workflows/display/types.py,sha256=Yko3zPXRjkkPjpx3gCSdNNjegh3CQYsoXFoQWWiTxWU,3777
|
112
113
|
vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
113
114
|
vellum_ee/workflows/display/utils/auto_layout.py,sha256=f4GiLn_LazweupfqTpubcdtdfE_vrOcmZudSsnYIY9E,3906
|
114
115
|
vellum_ee/workflows/display/utils/events.py,sha256=DE33uoKW78BZtITJ6L22dMZN3KR1BuZBVC98C_gIyzU,1943
|
@@ -121,7 +122,7 @@ vellum_ee/workflows/display/utils/tests/test_events.py,sha256=42IEBnMbaQrH8gigw5
|
|
121
122
|
vellum_ee/workflows/display/utils/vellum.py,sha256=sZwU0KdmZZTKWW62SyxJTl2tC8tN6p_BpZ-lDoinV-U,5670
|
122
123
|
vellum_ee/workflows/display/vellum.py,sha256=J2mdJZ1sdLW535DDUkq_Vm8Z572vhuxHxVZF9deKSdk,391
|
123
124
|
vellum_ee/workflows/display/workflows/__init__.py,sha256=JTB9ObEV3l4gGGdtfBHwVJtTTKC22uj-a-XjTVwXCyA,148
|
124
|
-
vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=
|
125
|
+
vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=x8HQK9AN2ql0_PFQAIilS4VEc_6h6Vd5tjhGYy7Hbs8,44329
|
125
126
|
vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=gxz76AeCqgAZ9D2lZeTiZzxY9eMgn3qOSfVgiqYcOh8,2028
|
126
127
|
vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=OKf_WVoPkYPrielOz8CyI5AjWt9MS2nSbWQKpF7HSLI,37847
|
127
128
|
vellum_ee/workflows/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -155,7 +156,7 @@ vellum/client/README.md,sha256=flqu57ubZNTfpq60CdLtJC9gp4WEkyjb_n_eZ4OYf9w,6497
|
|
155
156
|
vellum/client/__init__.py,sha256=T5Ht_w-Mk_9nzGqdadhQB8V20M0vYj7am06ut0A3P1o,73401
|
156
157
|
vellum/client/core/__init__.py,sha256=lTcqUPXcx4112yLDd70RAPeqq6tu3eFMe1pKOqkW9JQ,1562
|
157
158
|
vellum/client/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
|
158
|
-
vellum/client/core/client_wrapper.py,sha256=
|
159
|
+
vellum/client/core/client_wrapper.py,sha256=3LRRCUmekHH5eSClvUo_1GvPVridWvzGOYcx_DPDVZQ,2840
|
159
160
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
160
161
|
vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
|
161
162
|
vellum/client/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
|
@@ -1716,7 +1717,7 @@ vellum/utils/uuid.py,sha256=Ch6wWRgwICxLxJCTl5iE3EdRlZj2zADR-zUMUtjcMWM,214
|
|
1716
1717
|
vellum/version.py,sha256=jq-1PlAYxN9AXuaZqbYk9ak27SgE2lw9Ia5gx1b1gVI,76
|
1717
1718
|
vellum/workflows/README.md,sha256=hZdTKBIcsTKPofK68oPkBhyt0nnRh0csqC12k4FMHHA,3597
|
1718
1719
|
vellum/workflows/__init__.py,sha256=gd5AiZqVTcvqelhysG0jOWYfC6pJKRAVhS7qwf0bHU4,132
|
1719
|
-
vellum/workflows/constants.py,sha256=
|
1720
|
+
vellum/workflows/constants.py,sha256=ApFp3fm_DOuakvZV-c0ybieyVp-wELgHk-GTzDJoDCg,1429
|
1720
1721
|
vellum/workflows/context.py,sha256=ViyIeMDhUv-MhnynLaXPlvlbYxRU45ySvYidCNSbFZU,2458
|
1721
1722
|
vellum/workflows/descriptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1722
1723
|
vellum/workflows/descriptors/base.py,sha256=fRnRkECyDjfz2QEDCY9Q5mAerlJ6jR0R4nE-MP2VP_k,16558
|
@@ -1726,8 +1727,8 @@ vellum/workflows/descriptors/utils.py,sha256=7QvS_IOZWIoKvhNwpYBOTP3NasLSIBKTnhy
|
|
1726
1727
|
vellum/workflows/edges/__init__.py,sha256=wSkmAnz9xyi4vZwtDbKxwlplt2skD7n3NsxkvR_pUus,50
|
1727
1728
|
vellum/workflows/edges/edge.py,sha256=N0SnY3gKVuxImPAdCbPMPlHJIXbkQ3fwq_LbJRvVMFc,677
|
1728
1729
|
vellum/workflows/emitters/__init__.py,sha256=d9QFOI3eVg6rzpSFLvrjkDYXWikf1tcp3ruTRa2Boyc,143
|
1729
|
-
vellum/workflows/emitters/base.py,sha256=
|
1730
|
-
vellum/workflows/emitters/vellum_emitter.py,sha256=
|
1730
|
+
vellum/workflows/emitters/base.py,sha256=4hClzI-ue0kWiEnZ1T1zvGz2ZWnoWLCVF-seqHBMUC8,1144
|
1731
|
+
vellum/workflows/emitters/vellum_emitter.py,sha256=T77LuU31TBU75GOFyrWuJWyW5RzRNNH1_PFWcgdWMg0,4788
|
1731
1732
|
vellum/workflows/environment/__init__.py,sha256=TJz0m9dwIs6YOwCTeuN0HHsU-ecyjc1OJXx4AFy83EQ,121
|
1732
1733
|
vellum/workflows/environment/environment.py,sha256=Ck3RPKXJvtMGx_toqYQQQF-ZwXm5ijVwJpEPTeIJ4_Q,471
|
1733
1734
|
vellum/workflows/errors/__init__.py,sha256=tWGPu5xyAU8gRb8_bl0fL7OfU3wxQ9UH6qVwy4X4P_Q,113
|
@@ -1795,7 +1796,7 @@ vellum/workflows/graph/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
|
|
1795
1796
|
vellum/workflows/graph/tests/test_graph.py,sha256=0Pov0sCsxjzUDL9wy7xy9jFD-F2GsMJnZVEVFXzQGdM,15433
|
1796
1797
|
vellum/workflows/inputs/__init__.py,sha256=02pj0IbJkN1AxTreswK39cNi45tA8GWcAAdRJve4cuM,116
|
1797
1798
|
vellum/workflows/inputs/base.py,sha256=4kCRVz8AOqL6NgWZlfsBMnmCeDGDCTU0ImyBLlB0oaE,5203
|
1798
|
-
vellum/workflows/inputs/dataset_row.py,sha256=
|
1799
|
+
vellum/workflows/inputs/dataset_row.py,sha256=Szdb_RKysCEBRfy4B5LoXoPiTZPEFp_0_RqRZUZRGbU,1076
|
1799
1800
|
vellum/workflows/inputs/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1800
1801
|
vellum/workflows/inputs/tests/test_inputs.py,sha256=lioA8917mFLYq7Ml69UNkqUjcWbbxkxnpIEJ4FBaYBk,2206
|
1801
1802
|
vellum/workflows/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1805,7 +1806,7 @@ vellum/workflows/integrations/tests/test_mcp_service.py,sha256=q_DYrDkIqI4sQBNgI
|
|
1805
1806
|
vellum/workflows/logging.py,sha256=_a217XogktV4Ncz6xKFz7WfYmZAzkfVRVuC0rWob8ls,437
|
1806
1807
|
vellum/workflows/nodes/__init__.py,sha256=zymtc3_iW2rFmMR-sayTLuN6ZsAw8VnJweWPsjQk2-Q,1197
|
1807
1808
|
vellum/workflows/nodes/bases/__init__.py,sha256=cniHuz_RXdJ4TQgD8CBzoiKDiPxg62ErdVpCbWICX64,58
|
1808
|
-
vellum/workflows/nodes/bases/base.py,sha256=
|
1809
|
+
vellum/workflows/nodes/bases/base.py,sha256=WWRHbCk9Xf6FzY82af7WwGasF_h6nQAjMXjDDzHTVOs,20821
|
1809
1810
|
vellum/workflows/nodes/bases/base_adornment_node.py,sha256=hrgzuTetM4ynPd9YGHoK8Vwwn4XITi3aZZ_OCnQrq4Y,3433
|
1810
1811
|
vellum/workflows/nodes/bases/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1811
1812
|
vellum/workflows/nodes/bases/tests/test_base_adornment_node.py,sha256=fXZI9KqpS4XMBrBnIEkK3foHaBVvyHwYcQWWDKay7ic,1148
|
@@ -1843,9 +1844,9 @@ vellum/workflows/nodes/displayable/bases/api_node/node.py,sha256=cOYaIqimzDL6TuX
|
|
1843
1844
|
vellum/workflows/nodes/displayable/bases/api_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1844
1845
|
vellum/workflows/nodes/displayable/bases/api_node/tests/test_node.py,sha256=5C59vn_yg4r5EWioKIr658Jr1MSGX3YF4yKJokY37Xc,4726
|
1845
1846
|
vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py,sha256=Org3xTvgp1pA0uUXFfnJr29D3HzCey2lEdYF4zbIUgo,70
|
1846
|
-
vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=
|
1847
|
+
vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=w02vgydiwNoKru324QLSkH3BiGUvHTgKbf05BEx945s,4657
|
1847
1848
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py,sha256=Hl35IAoepRpE-j4cALaXVJIYTYOF3qszyVbxTj4kS1s,82
|
1848
|
-
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=
|
1849
|
+
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=ucbfX1HttsRDgngYnbS5MTytky-MAJW2ZkWgK4B-jI8,18600
|
1849
1850
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1850
1851
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py,sha256=xc53wGwVqxBnN7eoyWkJ-RJ-FeUpHKekkKjViASHAFg,27495
|
1851
1852
|
vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py,sha256=H9mM75EQpP6PUvsXCTbwjw4CqMMLf36m1G2XqiPEvH4,12139
|
@@ -1865,9 +1866,9 @@ vellum/workflows/nodes/displayable/conditional_node/__init__.py,sha256=AS_EIqFdU
|
|
1865
1866
|
vellum/workflows/nodes/displayable/conditional_node/node.py,sha256=71ZUNfTiD7t2Kai2ypw0tmv1lSf1brQaHAQD-SeUrGE,1101
|
1866
1867
|
vellum/workflows/nodes/displayable/conftest.py,sha256=K2kLM2JGAfcrmmd92u8DXInUO5klFdggPWblg5RVcx4,5729
|
1867
1868
|
vellum/workflows/nodes/displayable/final_output_node/__init__.py,sha256=G7VXM4OWpubvSJtVkGmMNeqgb9GkM7qZT838eL18XU4,72
|
1868
|
-
vellum/workflows/nodes/displayable/final_output_node/node.py,sha256=
|
1869
|
+
vellum/workflows/nodes/displayable/final_output_node/node.py,sha256=1_F9S7w-gIEUoXIdilgpqDeCKxJ0_J0oTYvE35dbjHk,4908
|
1869
1870
|
vellum/workflows/nodes/displayable/final_output_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1870
|
-
vellum/workflows/nodes/displayable/final_output_node/tests/test_node.py,sha256=
|
1871
|
+
vellum/workflows/nodes/displayable/final_output_node/tests/test_node.py,sha256=FR7lWUJlcWW1e9q_3vefi-b8_LA7CayZgTWZAnlAiLg,2387
|
1871
1872
|
vellum/workflows/nodes/displayable/guardrail_node/__init__.py,sha256=Ab5eXmOoBhyV4dMWdzh32HLUmnPIBEK_zFCT38C4Fng,68
|
1872
1873
|
vellum/workflows/nodes/displayable/guardrail_node/node.py,sha256=axYUojar_kdB3gi4LG3g9euJ8VkOxNtiFxJNI46v-SQ,5869
|
1873
1874
|
vellum/workflows/nodes/displayable/guardrail_node/test_node.py,sha256=SAGv6hSFcBwQkudn1VxtaKNsXSXWWELl3eK05zM6tS0,5410
|
@@ -1899,13 +1900,13 @@ vellum/workflows/nodes/displayable/tests/test_search_node_error_handling.py,sha2
|
|
1899
1900
|
vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py,sha256=VepO5z1277c1y5N6LLIC31nnWD1aak2m5oPFplfJHHs,6935
|
1900
1901
|
vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py,sha256=Bjv-wZyFgNaVZb9KEMMZd9lFoLzbPEPjEMpANizMZw4,2413
|
1901
1902
|
vellum/workflows/nodes/displayable/tool_calling_node/__init__.py,sha256=3n0-ysmFKsr40CVxPthc0rfJgqVJeZuUEsCmYudLVRg,117
|
1902
|
-
vellum/workflows/nodes/displayable/tool_calling_node/node.py,sha256=
|
1903
|
+
vellum/workflows/nodes/displayable/tool_calling_node/node.py,sha256=WXpCYhZ_wlyF_q0T769fw6CI_6-I9kvTiy1yfBGXjvE,8414
|
1903
1904
|
vellum/workflows/nodes/displayable/tool_calling_node/state.py,sha256=CcBVb_YtwfSSka4ze678k6-qwmzMSfjfVP8_Y95feSo,302
|
1904
1905
|
vellum/workflows/nodes/displayable/tool_calling_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1905
1906
|
vellum/workflows/nodes/displayable/tool_calling_node/tests/test_composio_service.py,sha256=in1fbEz5x1tx3uKv9YXdvOncsHucNL8Ro6Go7lBuuOQ,8962
|
1906
1907
|
vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py,sha256=GZoeybB9uM7ai8sBLAtUMHrMVgh-WrJDWrKZci6feDs,11892
|
1907
|
-
vellum/workflows/nodes/displayable/tool_calling_node/tests/test_utils.py,sha256=
|
1908
|
-
vellum/workflows/nodes/displayable/tool_calling_node/utils.py,sha256=
|
1908
|
+
vellum/workflows/nodes/displayable/tool_calling_node/tests/test_utils.py,sha256=EmKFA-ELdTzlK0xMqWnuSZPoGNLYCwk6b0amTqirZo0,11305
|
1909
|
+
vellum/workflows/nodes/displayable/tool_calling_node/utils.py,sha256=jqFpPDLZ463i2Lt7w_IN0fPypl1vrzZiYq2_1q9OyPo,22388
|
1909
1910
|
vellum/workflows/nodes/displayable/web_search_node/__init__.py,sha256=8FOnEP-n-U68cvxTlJW9wphIAGHq5aqjzLM-DoSSXnU,61
|
1910
1911
|
vellum/workflows/nodes/displayable/web_search_node/node.py,sha256=NQYux2bOtuBF5E4tn-fXi5y3btURPRrNqMSM9MAZYI4,5091
|
1911
1912
|
vellum/workflows/nodes/displayable/web_search_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1955,13 +1956,13 @@ vellum/workflows/state/store.py,sha256=uVe-oN73KwGV6M6YLhwZMMUQhzTQomsVfVnb8V91g
|
|
1955
1956
|
vellum/workflows/state/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1956
1957
|
vellum/workflows/state/tests/test_state.py,sha256=zEVFIY2any41X2BA5Us_qqKpzH5HRqmyrUJ04GTO0pU,7484
|
1957
1958
|
vellum/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1958
|
-
vellum/workflows/tests/test_dataset_row.py,sha256=
|
1959
|
+
vellum/workflows/tests/test_dataset_row.py,sha256=S8aIiYU9TRzJ8GTl5qCjnJ-fuHdxatHJFGLlKTVHPr4,4174
|
1959
1960
|
vellum/workflows/tests/test_sandbox.py,sha256=JKwaluI-lODQo7Ek9sjDstjL_WTdSqUlVik6ZVTfVOA,1826
|
1960
1961
|
vellum/workflows/tests/test_undefined.py,sha256=zMCVliCXVNLrlC6hEGyOWDnQADJ2g83yc5FIM33zuo8,353
|
1961
1962
|
vellum/workflows/types/__init__.py,sha256=KxUTMBGzuRCfiMqzzsykOeVvrrkaZmTTo1a7SLu8gRM,68
|
1962
1963
|
vellum/workflows/types/code_execution_node_wrappers.py,sha256=fewX9bqF_4TZuK-gZYIn12s31-k03vHMGRpvFAPm11Y,3206
|
1963
|
-
vellum/workflows/types/core.py,sha256=
|
1964
|
-
vellum/workflows/types/definition.py,sha256=
|
1964
|
+
vellum/workflows/types/core.py,sha256=yKm3sE02ult969q80DTmawiwYqodVjcAW-zlaUIgIv4,1495
|
1965
|
+
vellum/workflows/types/definition.py,sha256=rVoiXhj7xcQS793qjt2gdv64ywfQrRvujURjIWeC6gA,7240
|
1965
1966
|
vellum/workflows/types/generics.py,sha256=8jptbEx1fnJV0Lhj0MpCJOT6yNiEWeTOYOwrEAb5CRU,1576
|
1966
1967
|
vellum/workflows/types/stack.py,sha256=h7NE0vXR7l9DevFBIzIAk1Zh59K-kECQtDTKOUunwMY,1314
|
1967
1968
|
vellum/workflows/types/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1969,27 +1970,27 @@ vellum/workflows/types/tests/test_definition.py,sha256=rvDYjdJ1rvAv0qHBN7i7s-_WA
|
|
1969
1970
|
vellum/workflows/types/tests/test_utils.py,sha256=UnZog59tR577mVwqZRqqWn2fScoOU1H6up0EzS8zYhw,2536
|
1970
1971
|
vellum/workflows/types/utils.py,sha256=mTctHITBybpt4855x32oCKALBEcMNLn-9cCmfEKgJHQ,6498
|
1971
1972
|
vellum/workflows/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1972
|
-
vellum/workflows/utils/functions.py,sha256=
|
1973
|
+
vellum/workflows/utils/functions.py,sha256=CmdyfICCs0ZWmdrRpX8oITHkYcDrGu61Rrd_pVwl6ks,12723
|
1973
1974
|
vellum/workflows/utils/hmac.py,sha256=JJCczc6pyV6DuE1Oa0QVfYPUN_of3zEYmGFib3OZnrE,1135
|
1974
1975
|
vellum/workflows/utils/names.py,sha256=QtHquoaGqRseu5gg2OcVGI2d_CMcEOvjb9KspwH4C-A,552
|
1975
1976
|
vellum/workflows/utils/pydantic_schema.py,sha256=eR_bBtY-T0pttJP-ARwagSdCOnwPUtiT3cegm2lzDTQ,1310
|
1976
1977
|
vellum/workflows/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1977
|
-
vellum/workflows/utils/tests/test_functions.py,sha256=
|
1978
|
+
vellum/workflows/utils/tests/test_functions.py,sha256=PClZVGKTx4zLJwDmMM-NpLjat2M64B8rq26Nu4MEEIM,23974
|
1978
1979
|
vellum/workflows/utils/tests/test_names.py,sha256=DnRRnuORxQXx9ESegCzkxiWcHy2_bBi7lXgbFi3FZK8,757
|
1979
1980
|
vellum/workflows/utils/tests/test_uuids.py,sha256=i77ABQ0M3S-aFLzDXHJq_yr5FPkJEWCMBn1HJ3DObrE,437
|
1980
1981
|
vellum/workflows/utils/tests/test_vellum_variables.py,sha256=X7b-bbN3bFRx0WG31bowcaOgsXxEPYnh2sgpsqgKIsQ,2096
|
1981
1982
|
vellum/workflows/utils/uuids.py,sha256=IaZQANz7fhF7la0_J1O50Y6D2PIYv_taRDTRzBT9aWw,1284
|
1982
1983
|
vellum/workflows/utils/vellum_variables.py,sha256=Tgv09yYROgq8QZbrKKIOEdg0IQ8Vfgz_vRjY4tYzaTQ,7152
|
1983
1984
|
vellum/workflows/utils/zip.py,sha256=HVg_YZLmBOTXKaDV3Xhaf3V6sYnfqqZXQ8CpuafkbPY,1181
|
1984
|
-
vellum/workflows/vellum_client.py,sha256=
|
1985
|
+
vellum/workflows/vellum_client.py,sha256=3iDR7VV_NgLSm1iZQCKDvrmfEaX1bOJiU15QrxyHpv0,1237
|
1985
1986
|
vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
|
1986
|
-
vellum/workflows/workflows/base.py,sha256=
|
1987
|
+
vellum/workflows/workflows/base.py,sha256=PvrsKCEGsnBzKalYymErGmdnYUNBs7pJ5NEOCKL90CY,28615
|
1987
1988
|
vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
|
1988
1989
|
vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1989
1990
|
vellum/workflows/workflows/tests/test_base_workflow.py,sha256=ptMntHzVyy8ZuzNgeTuk7hREgKQ5UBdgq8VJFSGaW4Y,20832
|
1990
1991
|
vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
|
1991
|
-
vellum_ai-1.4.
|
1992
|
-
vellum_ai-1.4.
|
1993
|
-
vellum_ai-1.4.
|
1994
|
-
vellum_ai-1.4.
|
1995
|
-
vellum_ai-1.4.
|
1992
|
+
vellum_ai-1.4.2.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
1993
|
+
vellum_ai-1.4.2.dist-info/METADATA,sha256=2O0UVBAX-fWKzUzs1b8dWnKnfK2gpUNOTM1ZAz5alk0,5547
|
1994
|
+
vellum_ai-1.4.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
1995
|
+
vellum_ai-1.4.2.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
|
1996
|
+
vellum_ai-1.4.2.dist-info/RECORD,,
|
vellum_cli/tests/test_pull.py
CHANGED
@@ -1323,6 +1323,7 @@ MY_OTHER_VELLUM_API_KEY=aaabbbcccddd
|
|
1323
1323
|
vellum_client_class.assert_called_once_with(
|
1324
1324
|
api_key="aaabbbcccddd",
|
1325
1325
|
environment=mock.ANY,
|
1326
|
+
api_version=None,
|
1326
1327
|
)
|
1327
1328
|
|
1328
1329
|
# AND the vellum lock file should have been updated with the correct workspace
|
vellum_cli/tests/test_push.py
CHANGED
@@ -721,6 +721,7 @@ MY_OTHER_VELLUM_API_KEY=aaabbbcccddd
|
|
721
721
|
vellum_client_class.assert_called_once_with(
|
722
722
|
api_key="aaabbbcccddd",
|
723
723
|
environment=mock.ANY,
|
724
|
+
api_version=None,
|
724
725
|
)
|
725
726
|
|
726
727
|
# AND the vellum lock file should have been updated with the correct workspace
|
@@ -882,6 +883,7 @@ MY_OTHER_VELLUM_API_KEY=aaabbbcccddd
|
|
882
883
|
vellum_client_class.assert_called_once_with(
|
883
884
|
api_key="aaabbbcccddd",
|
884
885
|
environment=mock.ANY,
|
886
|
+
api_version=None,
|
885
887
|
)
|
886
888
|
|
887
889
|
# AND the vellum lock file should have the same two workflows
|
@@ -163,9 +163,7 @@ class BaseInlinePromptNodeDisplay(BaseNodeDisplay[_InlinePromptNodeType], Generi
|
|
163
163
|
elif callable(function):
|
164
164
|
normalized_functions = compile_function_definition(function)
|
165
165
|
elif isinstance(function, DeploymentDefinition):
|
166
|
-
normalized_functions = compile_workflow_deployment_function_definition(
|
167
|
-
function.model_dump(), display_context.client
|
168
|
-
)
|
166
|
+
normalized_functions = compile_workflow_deployment_function_definition(function, display_context.client)
|
169
167
|
else:
|
170
168
|
raise ValueError(f"Unsupported function type: {type(function)}")
|
171
169
|
return {
|
@@ -0,0 +1,78 @@
|
|
1
|
+
from vellum.workflows import BaseWorkflow
|
2
|
+
from vellum.workflows.nodes import BaseNode
|
3
|
+
from vellum.workflows.nodes.displayable.final_output_node import FinalOutputNode
|
4
|
+
from vellum.workflows.state.base import BaseState
|
5
|
+
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
6
|
+
|
7
|
+
|
8
|
+
def test_final_output_node_display__serialize_with_valid_types():
|
9
|
+
# GIVEN a node that outputs a str
|
10
|
+
class StringNode(BaseNode):
|
11
|
+
class Outputs:
|
12
|
+
result: str
|
13
|
+
|
14
|
+
# AND a FinalOutputNode with matching type to that node
|
15
|
+
class CorrectOutput(FinalOutputNode[BaseState, str]):
|
16
|
+
class Outputs(FinalOutputNode.Outputs):
|
17
|
+
value = StringNode.Outputs.result
|
18
|
+
|
19
|
+
# AND a workflow referencing the node
|
20
|
+
class MyWorkflow(BaseWorkflow):
|
21
|
+
graph = StringNode >> CorrectOutput
|
22
|
+
|
23
|
+
class Outputs(BaseWorkflow.Outputs):
|
24
|
+
final_result = CorrectOutput.Outputs.value
|
25
|
+
|
26
|
+
# WHEN we serialize the workflow
|
27
|
+
workflow_display = get_workflow_display(workflow_class=MyWorkflow)
|
28
|
+
|
29
|
+
# THEN serialization should succeed without raising validation errors
|
30
|
+
serialized_workflow: dict = workflow_display.serialize()
|
31
|
+
|
32
|
+
# AND the node should be properly serialized
|
33
|
+
assert "workflow_raw_data" in serialized_workflow
|
34
|
+
assert "nodes" in serialized_workflow["workflow_raw_data"]
|
35
|
+
|
36
|
+
# Find the terminal node in the serialized output
|
37
|
+
terminal_node = next(
|
38
|
+
node for node in serialized_workflow["workflow_raw_data"]["nodes"] if node["type"] == "TERMINAL"
|
39
|
+
)
|
40
|
+
assert terminal_node is not None
|
41
|
+
assert terminal_node["id"] == str(CorrectOutput.__id__)
|
42
|
+
|
43
|
+
|
44
|
+
def test_final_output_node_display__serialize_with_invalid_types_should_raise_error():
|
45
|
+
# GIVEN a node that outputs a str
|
46
|
+
class StringNode(BaseNode):
|
47
|
+
class Outputs:
|
48
|
+
result: str
|
49
|
+
|
50
|
+
# AND a FinalOutputNode with mismatched types (expects list but gets str)
|
51
|
+
class BadOutput(FinalOutputNode[BaseState, list]):
|
52
|
+
"""Output with type mismatch."""
|
53
|
+
|
54
|
+
class Outputs(FinalOutputNode.Outputs):
|
55
|
+
value = StringNode.Outputs.result # str type, conflicts with list
|
56
|
+
|
57
|
+
# AND a workflow referencing the node
|
58
|
+
class MyWorkflow(BaseWorkflow):
|
59
|
+
graph = StringNode >> BadOutput
|
60
|
+
|
61
|
+
class Outputs(BaseWorkflow.Outputs):
|
62
|
+
final_result = BadOutput.Outputs.value
|
63
|
+
|
64
|
+
# WHEN we attempt to serialize the workflow
|
65
|
+
workflow_display = get_workflow_display(workflow_class=MyWorkflow)
|
66
|
+
|
67
|
+
# THEN serialization should complete without raising an exception
|
68
|
+
serialized_workflow = workflow_display.serialize()
|
69
|
+
|
70
|
+
# AND the error should be captured in workflow_display.errors
|
71
|
+
errors = list(workflow_display.display_context.errors)
|
72
|
+
assert len(errors) == 1
|
73
|
+
assert "Output type mismatch" in str(errors[0])
|
74
|
+
assert "list" in str(errors[0])
|
75
|
+
assert "str" in str(errors[0])
|
76
|
+
|
77
|
+
# AND the serialized workflow should still be created
|
78
|
+
assert "workflow_raw_data" in serialized_workflow
|
@@ -437,6 +437,11 @@ def test_serialize_workflow():
|
|
437
437
|
"name": "max_prompt_iterations",
|
438
438
|
"value": {"type": "CONSTANT_VALUE", "value": {"type": "NUMBER", "value": 5.0}},
|
439
439
|
},
|
440
|
+
{
|
441
|
+
"id": "f92dc3ec-a19a-4491-a98a-2b2df322e2e3",
|
442
|
+
"name": "settings",
|
443
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "JSON", "value": None}},
|
444
|
+
},
|
440
445
|
],
|
441
446
|
"outputs": [
|
442
447
|
{"id": "e62bc785-a914-4066-b79e-8c89a5d0ec6c", "name": "text", "type": "STRING", "value": None},
|
@@ -206,6 +206,11 @@ def test_serialize_workflow():
|
|
206
206
|
"name": "max_prompt_iterations",
|
207
207
|
"value": {"type": "CONSTANT_VALUE", "value": {"type": "NUMBER", "value": 5.0}},
|
208
208
|
},
|
209
|
+
{
|
210
|
+
"id": "f92dc3ec-a19a-4491-a98a-2b2df322e2e3",
|
211
|
+
"name": "settings",
|
212
|
+
"value": {"type": "CONSTANT_VALUE", "value": {"type": "JSON", "value": None}},
|
213
|
+
},
|
209
214
|
],
|
210
215
|
"outputs": [
|
211
216
|
{"id": "e62bc785-a914-4066-b79e-8c89a5d0ec6c", "name": "text", "type": "STRING", "value": None},
|
@@ -62,6 +62,9 @@ class WorkflowDisplayContext:
|
|
62
62
|
|
63
63
|
raise error
|
64
64
|
|
65
|
+
def add_validation_error(self, error: Exception) -> None:
|
66
|
+
self._errors.append(error)
|
67
|
+
|
65
68
|
def add_invalid_node(self, node: Type[BaseNode]) -> None:
|
66
69
|
"""Track a node that failed to serialize."""
|
67
70
|
if node not in self._invalid_nodes:
|
@@ -196,6 +196,12 @@ class BaseWorkflowDisplay(Generic[WorkflowType]):
|
|
196
196
|
node_display = self.display_context.node_displays[node]
|
197
197
|
|
198
198
|
try:
|
199
|
+
try:
|
200
|
+
node.__validate__()
|
201
|
+
except ValueError as validation_error:
|
202
|
+
# Only collect node validation errors directly to errors list, don't raise them
|
203
|
+
self.display_context.add_validation_error(validation_error)
|
204
|
+
|
199
205
|
serialized_node = node_display.serialize(self.display_context)
|
200
206
|
except (NotImplementedError, NodeValidationError) as e:
|
201
207
|
self.display_context.add_error(e)
|
File without changes
|
File without changes
|
File without changes
|