vellum-ai 0.13.9__py3-none-any.whl → 0.13.11__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 +1 -1
- vellum/workflows/descriptors/utils.py +1 -1
- vellum/workflows/errors/types.py +21 -0
- vellum/workflows/nodes/bases/base.py +1 -1
- vellum/workflows/nodes/displayable/api_node/node.py +4 -1
- vellum/workflows/nodes/displayable/bases/api_node/node.py +4 -1
- vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +18 -2
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +4 -0
- vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +4 -0
- vellum/workflows/nodes/displayable/bases/search_node.py +4 -0
- vellum/workflows/nodes/displayable/bases/tests/test_utils.py +18 -0
- vellum/workflows/nodes/displayable/bases/utils.py +8 -1
- vellum/workflows/nodes/displayable/code_execution_node/node.py +4 -1
- vellum/workflows/nodes/displayable/conditional_node/node.py +4 -0
- vellum/workflows/nodes/displayable/final_output_node/node.py +4 -0
- vellum/workflows/nodes/displayable/guardrail_node/node.py +4 -1
- vellum/workflows/nodes/displayable/inline_prompt_node/node.py +4 -0
- vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py +55 -0
- vellum/workflows/nodes/displayable/merge_node/node.py +3 -1
- vellum/workflows/nodes/displayable/note_node/node.py +4 -0
- vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +4 -0
- vellum/workflows/nodes/displayable/search_node/node.py +4 -0
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +4 -1
- {vellum_ai-0.13.9.dist-info → vellum_ai-0.13.11.dist-info}/METADATA +1 -1
- {vellum_ai-0.13.9.dist-info → vellum_ai-0.13.11.dist-info}/RECORD +59 -59
- vellum_cli/__init__.py +9 -1
- vellum_cli/config.py +29 -1
- vellum_cli/push.py +24 -3
- vellum_cli/tests/conftest.py +3 -0
- vellum_cli/tests/test_pull.py +6 -0
- vellum_cli/tests/test_push.py +88 -1
- vellum_ee/workflows/display/nodes/base_node_display.py +207 -3
- vellum_ee/workflows/display/nodes/base_node_vellum_display.py +16 -1
- vellum_ee/workflows/display/nodes/get_node_display_class.py +6 -4
- vellum_ee/workflows/display/nodes/vellum/__init__.py +0 -2
- vellum_ee/workflows/display/nodes/vellum/conditional_node.py +2 -1
- vellum_ee/workflows/display/nodes/vellum/error_node.py +9 -3
- vellum_ee/workflows/display/nodes/vellum/tests/test_error_node.py +44 -0
- vellum_ee/workflows/display/nodes/vellum/try_node.py +8 -2
- vellum_ee/workflows/display/nodes/vellum/utils.py +0 -69
- vellum_ee/workflows/display/tests/test_vellum_workflow_display.py +56 -0
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py +4 -3
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +146 -26
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +11 -11
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py +7 -7
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py +33 -35
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py +4 -4
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +5 -5
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_error_node_serialization.py +15 -1
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_generic_node_serialization.py +1 -1
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +6 -3
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +6 -3
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +3 -3
- vellum_ee/workflows/display/utils/vellum.py +74 -4
- vellum_ee/workflows/display/workflows/base_workflow_display.py +6 -4
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py +26 -14
- vellum_ee/workflows/display/nodes/vellum/base_node.py +0 -192
- {vellum_ai-0.13.9.dist-info → vellum_ai-0.13.11.dist-info}/LICENSE +0 -0
- {vellum_ai-0.13.9.dist-info → vellum_ai-0.13.11.dist-info}/WHEEL +0 -0
- {vellum_ai-0.13.9.dist-info → vellum_ai-0.13.11.dist-info}/entry_points.txt +0 -0
@@ -18,7 +18,7 @@ class BaseClientWrapper:
|
|
18
18
|
headers: typing.Dict[str, str] = {
|
19
19
|
"X-Fern-Language": "Python",
|
20
20
|
"X-Fern-SDK-Name": "vellum-ai",
|
21
|
-
"X-Fern-SDK-Version": "0.13.
|
21
|
+
"X-Fern-SDK-Version": "0.13.11",
|
22
22
|
}
|
23
23
|
headers["X_API_KEY"] = self.api_key
|
24
24
|
return headers
|
@@ -108,7 +108,7 @@ def is_unresolved(value: Any) -> bool:
|
|
108
108
|
if isinstance(value, Mapping):
|
109
109
|
return any(is_unresolved(item) for item in value.values())
|
110
110
|
|
111
|
-
if isinstance(value, Sequence):
|
111
|
+
if isinstance(value, Sequence) and not isinstance(value, str):
|
112
112
|
return any(is_unresolved(item) for item in value)
|
113
113
|
|
114
114
|
if isinstance(value, Set):
|
vellum/workflows/errors/types.py
CHANGED
@@ -61,3 +61,24 @@ def workflow_event_error_to_workflow_error(error: WorkflowEventError) -> Workflo
|
|
61
61
|
message=error.message,
|
62
62
|
code=_WORKFLOW_EVENT_ERROR_CODE_TO_WORKFLOW_ERROR_CODE.get(error.code, WorkflowErrorCode.INTERNAL_ERROR),
|
63
63
|
)
|
64
|
+
|
65
|
+
|
66
|
+
_WORKFLOW_ERROR_CODE_TO_VELLUM_ERROR_CODE: Dict[WorkflowErrorCode, VellumErrorCodeEnum] = {
|
67
|
+
WorkflowErrorCode.INVALID_WORKFLOW: "INVALID_REQUEST",
|
68
|
+
WorkflowErrorCode.INVALID_INPUTS: "INVALID_INPUTS",
|
69
|
+
WorkflowErrorCode.INVALID_OUTPUTS: "INVALID_REQUEST",
|
70
|
+
WorkflowErrorCode.INVALID_STATE: "INVALID_REQUEST",
|
71
|
+
WorkflowErrorCode.INVALID_TEMPLATE: "INVALID_INPUTS",
|
72
|
+
WorkflowErrorCode.INTERNAL_ERROR: "INTERNAL_SERVER_ERROR",
|
73
|
+
WorkflowErrorCode.NODE_EXECUTION: "USER_DEFINED_ERROR",
|
74
|
+
WorkflowErrorCode.PROVIDER_ERROR: "PROVIDER_ERROR",
|
75
|
+
WorkflowErrorCode.USER_DEFINED_ERROR: "USER_DEFINED_ERROR",
|
76
|
+
WorkflowErrorCode.WORKFLOW_CANCELLED: "REQUEST_TIMEOUT",
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
def workflow_error_to_vellum_error(error: WorkflowError) -> VellumError:
|
81
|
+
return VellumError(
|
82
|
+
message=error.message,
|
83
|
+
code=_WORKFLOW_ERROR_CODE_TO_VELLUM_ERROR_CODE.get(error.code, "INTERNAL_SERVER_ERROR"),
|
84
|
+
)
|
@@ -237,7 +237,7 @@ class BaseNode(Generic[StateType], metaclass=BaseNodeMeta):
|
|
237
237
|
|
238
238
|
class Trigger(metaclass=_BaseNodeTriggerMeta):
|
239
239
|
node_class: Type["BaseNode"]
|
240
|
-
merge_behavior = MergeBehavior.
|
240
|
+
merge_behavior = MergeBehavior.AWAIT_ATTRIBUTES
|
241
241
|
|
242
242
|
@classmethod
|
243
243
|
def should_initiate(
|
@@ -2,7 +2,7 @@ from typing import Optional, Union
|
|
2
2
|
|
3
3
|
from vellum.workflows.constants import AuthorizationType
|
4
4
|
from vellum.workflows.nodes.displayable.bases.api_node import BaseAPINode
|
5
|
-
from vellum.workflows.types.core import VellumSecret
|
5
|
+
from vellum.workflows.types.core import MergeBehavior, VellumSecret
|
6
6
|
|
7
7
|
|
8
8
|
class APINode(BaseAPINode):
|
@@ -27,6 +27,9 @@ class APINode(BaseAPINode):
|
|
27
27
|
api_key_header_value: Optional[Union[str, VellumSecret]] = None
|
28
28
|
bearer_token_value: Optional[Union[str, VellumSecret]] = None
|
29
29
|
|
30
|
+
class Trigger(BaseAPINode.Trigger):
|
31
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
32
|
+
|
30
33
|
def run(self) -> BaseAPINode.Outputs:
|
31
34
|
headers = self.headers or {}
|
32
35
|
header_overrides = {}
|
@@ -8,7 +8,7 @@ from vellum.workflows.errors.types import WorkflowErrorCode
|
|
8
8
|
from vellum.workflows.exceptions import NodeException
|
9
9
|
from vellum.workflows.nodes.bases import BaseNode
|
10
10
|
from vellum.workflows.outputs import BaseOutputs
|
11
|
-
from vellum.workflows.types.core import Json, VellumSecret
|
11
|
+
from vellum.workflows.types.core import Json, MergeBehavior, VellumSecret
|
12
12
|
from vellum.workflows.types.generics import StateType
|
13
13
|
|
14
14
|
|
@@ -23,6 +23,9 @@ class BaseAPINode(BaseNode, Generic[StateType]):
|
|
23
23
|
headers: Optional[Dict[str, Union[str, VellumSecret]]] - The headers to send in the request.
|
24
24
|
"""
|
25
25
|
|
26
|
+
class Trigger(BaseNode.Trigger):
|
27
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
28
|
+
|
26
29
|
url: str
|
27
30
|
method: APIRequestMethod
|
28
31
|
data: Optional[str] = None
|
@@ -2,12 +2,13 @@ from abc import abstractmethod
|
|
2
2
|
from typing import ClassVar, Generator, Generic, Iterator, List, Optional, Union
|
3
3
|
|
4
4
|
from vellum import AdHocExecutePromptEvent, ExecutePromptEvent, PromptOutput
|
5
|
+
from vellum.client.core.api_error import ApiError
|
5
6
|
from vellum.core import RequestOptions
|
6
7
|
from vellum.workflows.errors.types import WorkflowErrorCode, vellum_error_to_workflow_error
|
7
8
|
from vellum.workflows.exceptions import NodeException
|
8
9
|
from vellum.workflows.nodes.bases import BaseNode
|
9
10
|
from vellum.workflows.outputs.base import BaseOutput, BaseOutputs
|
10
|
-
from vellum.workflows.types.core import EntityInputsInterface
|
11
|
+
from vellum.workflows.types.core import EntityInputsInterface, MergeBehavior
|
11
12
|
from vellum.workflows.types.generics import StateType
|
12
13
|
|
13
14
|
|
@@ -17,6 +18,9 @@ class BasePromptNode(BaseNode, Generic[StateType]):
|
|
17
18
|
|
18
19
|
request_options: Optional[RequestOptions] = None
|
19
20
|
|
21
|
+
class Trigger(BaseNode.Trigger):
|
22
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
23
|
+
|
20
24
|
class Outputs(BaseOutputs):
|
21
25
|
results: List[PromptOutput]
|
22
26
|
|
@@ -33,7 +37,19 @@ class BasePromptNode(BaseNode, Generic[StateType]):
|
|
33
37
|
)
|
34
38
|
|
35
39
|
def _process_prompt_event_stream(self) -> Generator[BaseOutput, None, Optional[List[PromptOutput]]]:
|
36
|
-
|
40
|
+
try:
|
41
|
+
prompt_event_stream = self._get_prompt_event_stream()
|
42
|
+
except ApiError as e:
|
43
|
+
if e.status_code and e.status_code >= 400 and e.status_code < 500 and isinstance(e.body, dict):
|
44
|
+
raise NodeException(
|
45
|
+
message=e.body.get("detail", "Failed to execute prompt"),
|
46
|
+
code=WorkflowErrorCode.INVALID_INPUTS,
|
47
|
+
) from e
|
48
|
+
|
49
|
+
raise NodeException(
|
50
|
+
message="Failed to execute prompt",
|
51
|
+
code=WorkflowErrorCode.INTERNAL_ERROR,
|
52
|
+
) from e
|
37
53
|
|
38
54
|
outputs: Optional[List[PromptOutput]] = None
|
39
55
|
for event in prompt_event_stream:
|
@@ -23,6 +23,7 @@ from vellum.workflows.events.types import default_serializer
|
|
23
23
|
from vellum.workflows.exceptions import NodeException
|
24
24
|
from vellum.workflows.nodes.displayable.bases.base_prompt_node import BasePromptNode
|
25
25
|
from vellum.workflows.nodes.displayable.bases.inline_prompt_node.constants import DEFAULT_PROMPT_PARAMETERS
|
26
|
+
from vellum.workflows.types import MergeBehavior
|
26
27
|
from vellum.workflows.types.generics import StateType
|
27
28
|
from vellum.workflows.utils.functions import compile_function_definition
|
28
29
|
|
@@ -51,6 +52,9 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
|
|
51
52
|
parameters: PromptParameters = DEFAULT_PROMPT_PARAMETERS
|
52
53
|
expand_meta: Optional[AdHocExpandMeta] = OMIT
|
53
54
|
|
55
|
+
class Trigger(BasePromptNode.Trigger):
|
56
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
57
|
+
|
54
58
|
def _get_prompt_event_stream(self) -> Iterator[AdHocExecutePromptEvent]:
|
55
59
|
input_variables, input_values = self._compile_prompt_inputs()
|
56
60
|
parent_context = get_parent_context()
|
@@ -17,6 +17,7 @@ from vellum.workflows.context import get_parent_context
|
|
17
17
|
from vellum.workflows.errors import WorkflowErrorCode
|
18
18
|
from vellum.workflows.exceptions import NodeException
|
19
19
|
from vellum.workflows.nodes.displayable.bases.base_prompt_node import BasePromptNode
|
20
|
+
from vellum.workflows.types import MergeBehavior
|
20
21
|
from vellum.workflows.types.generics import StateType
|
21
22
|
|
22
23
|
|
@@ -47,6 +48,9 @@ class BasePromptDeploymentNode(BasePromptNode, Generic[StateType]):
|
|
47
48
|
expand_raw: Optional[Sequence[str]] = OMIT
|
48
49
|
metadata: Optional[Dict[str, Optional[Any]]] = OMIT
|
49
50
|
|
51
|
+
class Trigger(BasePromptNode.Trigger):
|
52
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
53
|
+
|
50
54
|
def _get_prompt_event_stream(self) -> Iterator[ExecutePromptEvent]:
|
51
55
|
current_parent_context = get_parent_context()
|
52
56
|
parent_context = current_parent_context.model_dump() if current_parent_context else None
|
@@ -17,6 +17,7 @@ from vellum.workflows.exceptions import NodeException
|
|
17
17
|
from vellum.workflows.nodes.bases import BaseNode
|
18
18
|
from vellum.workflows.nodes.displayable.bases.types import SearchFilters
|
19
19
|
from vellum.workflows.outputs import BaseOutputs
|
20
|
+
from vellum.workflows.types import MergeBehavior
|
20
21
|
from vellum.workflows.types.generics import StateType
|
21
22
|
|
22
23
|
DEFAULT_SEARCH_WEIGHTS = 0.8
|
@@ -81,6 +82,9 @@ class BaseSearchNode(BaseNode[StateType], Generic[StateType]):
|
|
81
82
|
|
82
83
|
request_options: Optional[RequestOptions] = None
|
83
84
|
|
85
|
+
class Trigger(BaseNode.Trigger):
|
86
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
87
|
+
|
84
88
|
class Outputs(BaseOutputs):
|
85
89
|
"""
|
86
90
|
The outputs of the SearchNode.
|
@@ -1,8 +1,11 @@
|
|
1
1
|
import pytest
|
2
2
|
import enum
|
3
3
|
|
4
|
+
from pydantic import BaseModel
|
5
|
+
|
4
6
|
from vellum.client.types.chat_history_vellum_value import ChatHistoryVellumValue
|
5
7
|
from vellum.client.types.chat_message import ChatMessage
|
8
|
+
from vellum.client.types.error_vellum_value import ErrorVellumValue
|
6
9
|
from vellum.client.types.json_vellum_value import JsonVellumValue
|
7
10
|
from vellum.client.types.number_vellum_value import NumberVellumValue
|
8
11
|
from vellum.client.types.search_result import SearchResult
|
@@ -10,6 +13,8 @@ from vellum.client.types.search_result_document import SearchResultDocument
|
|
10
13
|
from vellum.client.types.search_results_vellum_value import SearchResultsVellumValue
|
11
14
|
from vellum.client.types.string_vellum_value import StringVellumValue
|
12
15
|
from vellum.client.types.string_vellum_value_request import StringVellumValueRequest
|
16
|
+
from vellum.client.types.vellum_error import VellumError
|
17
|
+
from vellum.workflows.errors.types import WorkflowError, WorkflowErrorCode
|
13
18
|
from vellum.workflows.nodes.displayable.bases.utils import primitive_to_vellum_value, primitive_to_vellum_value_request
|
14
19
|
|
15
20
|
|
@@ -17,6 +22,10 @@ class MockEnum(enum.Enum):
|
|
17
22
|
FOO = "foo"
|
18
23
|
|
19
24
|
|
25
|
+
class RandomPydanticModel(BaseModel):
|
26
|
+
foo: str
|
27
|
+
|
28
|
+
|
20
29
|
@pytest.mark.parametrize(
|
21
30
|
["value", "expected_output"],
|
22
31
|
[
|
@@ -51,6 +60,15 @@ class MockEnum(enum.Enum):
|
|
51
60
|
(StringVellumValue(value="hello"), StringVellumValue(value="hello")),
|
52
61
|
(StringVellumValueRequest(value="hello"), StringVellumValueRequest(value="hello")),
|
53
62
|
({"foo": "bar"}, JsonVellumValue(value={"foo": "bar"})),
|
63
|
+
(
|
64
|
+
VellumError(message="hello", code="USER_DEFINED_ERROR"),
|
65
|
+
ErrorVellumValue(value=VellumError(message="hello", code="USER_DEFINED_ERROR")),
|
66
|
+
),
|
67
|
+
(
|
68
|
+
WorkflowError(message="hello", code=WorkflowErrorCode.USER_DEFINED_ERROR),
|
69
|
+
ErrorVellumValue(value=VellumError(message="hello", code="USER_DEFINED_ERROR")),
|
70
|
+
),
|
71
|
+
(RandomPydanticModel(foo="bar"), JsonVellumValue(value={"foo": "bar"})),
|
54
72
|
],
|
55
73
|
)
|
56
74
|
def test_primitive_to_vellum_value(value, expected_output):
|
@@ -25,8 +25,11 @@ from vellum.client.types.search_results_vellum_value import SearchResultsVellumV
|
|
25
25
|
from vellum.client.types.search_results_vellum_value_request import SearchResultsVellumValueRequest
|
26
26
|
from vellum.client.types.string_vellum_value import StringVellumValue
|
27
27
|
from vellum.client.types.string_vellum_value_request import StringVellumValueRequest
|
28
|
+
from vellum.client.types.vellum_error import VellumError
|
28
29
|
from vellum.client.types.vellum_value import VellumValue
|
29
30
|
from vellum.client.types.vellum_value_request import VellumValueRequest
|
31
|
+
from vellum.workflows.errors.types import WorkflowError, workflow_error_to_vellum_error
|
32
|
+
from vellum.workflows.state.encoder import DefaultStateEncoder
|
30
33
|
|
31
34
|
VELLUM_VALUE_REQUEST_TUPLE = (
|
32
35
|
StringVellumValueRequest,
|
@@ -63,6 +66,10 @@ def primitive_to_vellum_value(value: Any) -> VellumValue:
|
|
63
66
|
):
|
64
67
|
search_results = cast(Union[List[SearchResultRequest], List[SearchResult]], value)
|
65
68
|
return SearchResultsVellumValue(value=search_results)
|
69
|
+
elif isinstance(value, VellumError):
|
70
|
+
return ErrorVellumValue(value=value)
|
71
|
+
elif isinstance(value, WorkflowError):
|
72
|
+
return ErrorVellumValue(value=workflow_error_to_vellum_error(value))
|
66
73
|
elif isinstance(
|
67
74
|
value,
|
68
75
|
(
|
@@ -88,7 +95,7 @@ def primitive_to_vellum_value(value: Any) -> VellumValue:
|
|
88
95
|
return value # type: ignore
|
89
96
|
|
90
97
|
try:
|
91
|
-
json_value = json.dumps(value)
|
98
|
+
json_value = json.dumps(value, cls=DefaultStateEncoder)
|
92
99
|
except json.JSONDecodeError:
|
93
100
|
raise ValueError(f"Unsupported variable type: {value.__class__.__name__}")
|
94
101
|
|
@@ -26,7 +26,7 @@ from vellum.workflows.nodes.bases import BaseNode
|
|
26
26
|
from vellum.workflows.nodes.bases.base import BaseNodeMeta
|
27
27
|
from vellum.workflows.nodes.displayable.code_execution_node.utils import read_file_from_path
|
28
28
|
from vellum.workflows.outputs.base import BaseOutputs
|
29
|
-
from vellum.workflows.types.core import EntityInputsInterface, VellumSecret
|
29
|
+
from vellum.workflows.types.core import EntityInputsInterface, MergeBehavior, VellumSecret
|
30
30
|
from vellum.workflows.types.generics import StateType
|
31
31
|
from vellum.workflows.types.utils import get_original_base
|
32
32
|
from vellum.workflows.utils.vellum_variables import primitive_type_to_vellum_variable_type
|
@@ -82,6 +82,9 @@ class CodeExecutionNode(BaseNode[StateType], Generic[StateType, _OutputType], me
|
|
82
82
|
|
83
83
|
request_options: Optional[RequestOptions] = None
|
84
84
|
|
85
|
+
class Trigger(BaseNode.Trigger):
|
86
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
87
|
+
|
85
88
|
class Outputs(BaseOutputs):
|
86
89
|
# We use our mypy plugin to override the _OutputType with the actual output type
|
87
90
|
# for downstream references to this output.
|
@@ -6,6 +6,7 @@ from vellum.workflows.ports.node_ports import NodePorts
|
|
6
6
|
from vellum.workflows.ports.port import Port
|
7
7
|
from vellum.workflows.ports.utils import validate_ports
|
8
8
|
from vellum.workflows.state.base import BaseState
|
9
|
+
from vellum.workflows.types import MergeBehavior
|
9
10
|
|
10
11
|
|
11
12
|
class ConditionalNode(BaseNode):
|
@@ -14,6 +15,9 @@ class ConditionalNode(BaseNode):
|
|
14
15
|
Vellum's Conditional Node, and for most cases, you should extend `BaseNode.Ports` directly.
|
15
16
|
"""
|
16
17
|
|
18
|
+
class Trigger(BaseNode.Trigger):
|
19
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
20
|
+
|
17
21
|
class Ports(NodePorts):
|
18
22
|
def __call__(self, outputs: BaseOutputs, state: BaseState) -> Set[Port]:
|
19
23
|
all_ports = [port for port in self.__class__]
|
@@ -2,6 +2,7 @@ from typing import Any, Dict, Generic, Tuple, Type, TypeVar, get_args
|
|
2
2
|
|
3
3
|
from vellum.workflows.nodes.bases import BaseNode
|
4
4
|
from vellum.workflows.nodes.bases.base import BaseNodeMeta
|
5
|
+
from vellum.workflows.types import MergeBehavior
|
5
6
|
from vellum.workflows.types.generics import StateType
|
6
7
|
from vellum.workflows.types.utils import get_original_base
|
7
8
|
|
@@ -41,6 +42,9 @@ class FinalOutputNode(BaseNode[StateType], Generic[StateType, _OutputType], meta
|
|
41
42
|
This provides backward compatibility with Vellum's Final Output Node.
|
42
43
|
"""
|
43
44
|
|
45
|
+
class Trigger(BaseNode.Trigger):
|
46
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
47
|
+
|
44
48
|
class Outputs(BaseNode.Outputs):
|
45
49
|
# We use our mypy plugin to override the _OutputType with the actual output type
|
46
50
|
# for downstream references to this output.
|
@@ -8,7 +8,7 @@ from vellum.workflows.errors.types import WorkflowErrorCode
|
|
8
8
|
from vellum.workflows.exceptions import NodeException
|
9
9
|
from vellum.workflows.nodes.bases import BaseNode
|
10
10
|
from vellum.workflows.outputs.base import BaseOutputs
|
11
|
-
from vellum.workflows.types.core import EntityInputsInterface
|
11
|
+
from vellum.workflows.types.core import EntityInputsInterface, MergeBehavior
|
12
12
|
from vellum.workflows.types.generics import StateType
|
13
13
|
|
14
14
|
|
@@ -29,6 +29,9 @@ class GuardrailNode(BaseNode[StateType], Generic[StateType]):
|
|
29
29
|
|
30
30
|
request_options: Optional[RequestOptions] = None
|
31
31
|
|
32
|
+
class Trigger(BaseNode.Trigger):
|
33
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
34
|
+
|
32
35
|
class Outputs(BaseOutputs):
|
33
36
|
score: float
|
34
37
|
|
@@ -5,6 +5,7 @@ from vellum.workflows.errors import WorkflowErrorCode
|
|
5
5
|
from vellum.workflows.exceptions import NodeException
|
6
6
|
from vellum.workflows.nodes.displayable.bases import BaseInlinePromptNode as BaseInlinePromptNode
|
7
7
|
from vellum.workflows.outputs import BaseOutput
|
8
|
+
from vellum.workflows.types import MergeBehavior
|
8
9
|
from vellum.workflows.types.generics import StateType
|
9
10
|
|
10
11
|
|
@@ -21,6 +22,9 @@ class InlinePromptNode(BaseInlinePromptNode[StateType]):
|
|
21
22
|
request_options: Optional[RequestOptions] - The request options to use for the Prompt Execution
|
22
23
|
"""
|
23
24
|
|
25
|
+
class Trigger(BaseInlinePromptNode.Trigger):
|
26
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
27
|
+
|
24
28
|
class Outputs(BaseInlinePromptNode.Outputs):
|
25
29
|
"""
|
26
30
|
The outputs of the InlinePromptNode.
|
@@ -1,7 +1,9 @@
|
|
1
|
+
import pytest
|
1
2
|
from dataclasses import dataclass
|
2
3
|
from uuid import uuid4
|
3
4
|
from typing import Any, Iterator, List
|
4
5
|
|
6
|
+
from vellum.client.core.api_error import ApiError
|
5
7
|
from vellum.client.core.pydantic_utilities import UniversalBaseModel
|
6
8
|
from vellum.client.types.execute_prompt_event import ExecutePromptEvent
|
7
9
|
from vellum.client.types.fulfilled_execute_prompt_event import FulfilledExecutePromptEvent
|
@@ -12,6 +14,8 @@ from vellum.client.types.initiated_execute_prompt_event import InitiatedExecuteP
|
|
12
14
|
from vellum.client.types.prompt_output import PromptOutput
|
13
15
|
from vellum.client.types.prompt_request_json_input import PromptRequestJsonInput
|
14
16
|
from vellum.client.types.string_vellum_value import StringVellumValue
|
17
|
+
from vellum.workflows.errors.types import WorkflowErrorCode
|
18
|
+
from vellum.workflows.exceptions import NodeException
|
15
19
|
from vellum.workflows.nodes.displayable.inline_prompt_node.node import InlinePromptNode
|
16
20
|
|
17
21
|
|
@@ -126,3 +130,54 @@ def test_inline_prompt_node__function_definitions(vellum_adhoc_prompt_client):
|
|
126
130
|
"name": "my_function"
|
127
131
|
}"""
|
128
132
|
)
|
133
|
+
|
134
|
+
|
135
|
+
@pytest.mark.parametrize(
|
136
|
+
["exception", "expected_code", "expected_message"],
|
137
|
+
[
|
138
|
+
(
|
139
|
+
ApiError(status_code=404, body={"detail": "Model not found"}),
|
140
|
+
WorkflowErrorCode.INVALID_INPUTS,
|
141
|
+
"Model not found",
|
142
|
+
),
|
143
|
+
(
|
144
|
+
ApiError(status_code=404, body={"message": "Model not found"}),
|
145
|
+
WorkflowErrorCode.INVALID_INPUTS,
|
146
|
+
"Failed to execute prompt",
|
147
|
+
),
|
148
|
+
(
|
149
|
+
ApiError(status_code=404, body="Model not found"),
|
150
|
+
WorkflowErrorCode.INTERNAL_ERROR,
|
151
|
+
"Failed to execute prompt",
|
152
|
+
),
|
153
|
+
(
|
154
|
+
ApiError(status_code=None, body={"detail": "Model not found"}),
|
155
|
+
WorkflowErrorCode.INTERNAL_ERROR,
|
156
|
+
"Failed to execute prompt",
|
157
|
+
),
|
158
|
+
(
|
159
|
+
ApiError(status_code=500, body={"detail": "Model not found"}),
|
160
|
+
WorkflowErrorCode.INTERNAL_ERROR,
|
161
|
+
"Failed to execute prompt",
|
162
|
+
),
|
163
|
+
],
|
164
|
+
ids=["404", "invalid_dict", "invalid_body", "no_status_code", "500"],
|
165
|
+
)
|
166
|
+
def test_inline_prompt_node__api_error__invalid_inputs_node_exception(
|
167
|
+
vellum_adhoc_prompt_client, exception, expected_code, expected_message
|
168
|
+
):
|
169
|
+
# GIVEN a prompt node with an invalid model name
|
170
|
+
class MyNode(InlinePromptNode):
|
171
|
+
ml_model = "my-invalid-model"
|
172
|
+
blocks = []
|
173
|
+
|
174
|
+
# AND the adhoc prompt client raises a 4xx error
|
175
|
+
vellum_adhoc_prompt_client.adhoc_execute_prompt_stream.side_effect = exception
|
176
|
+
|
177
|
+
# WHEN the node is run
|
178
|
+
with pytest.raises(NodeException) as e:
|
179
|
+
list(MyNode().run())
|
180
|
+
|
181
|
+
# THEN the node raises the correct NodeException
|
182
|
+
assert e.value.code == expected_code
|
183
|
+
assert e.value.message == expected_message
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from vellum.workflows.nodes.bases import BaseNode
|
2
|
+
from vellum.workflows.types import MergeBehavior
|
2
3
|
|
3
4
|
|
4
5
|
class MergeNode(BaseNode):
|
@@ -7,4 +8,5 @@ class MergeNode(BaseNode):
|
|
7
8
|
with Vellum's Merge Node, and for most cases, you should extend from `BaseNode.Trigger` directly.
|
8
9
|
"""
|
9
10
|
|
10
|
-
|
11
|
+
class Trigger(BaseNode.Trigger):
|
12
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
@@ -1,4 +1,5 @@
|
|
1
1
|
from vellum.workflows.nodes.bases import BaseNode
|
2
|
+
from vellum.workflows.types import MergeBehavior
|
2
3
|
|
3
4
|
|
4
5
|
class NoteNode(BaseNode):
|
@@ -6,5 +7,8 @@ class NoteNode(BaseNode):
|
|
6
7
|
A no-op Node purely used to display a note in the Vellum UI.
|
7
8
|
"""
|
8
9
|
|
10
|
+
class Trigger(BaseNode.Trigger):
|
11
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
12
|
+
|
9
13
|
def run(self) -> BaseNode.Outputs:
|
10
14
|
raise RuntimeError("NoteNode should never be run")
|
@@ -4,6 +4,7 @@ from vellum.workflows.errors import WorkflowErrorCode
|
|
4
4
|
from vellum.workflows.exceptions import NodeException
|
5
5
|
from vellum.workflows.nodes.displayable.bases import BasePromptDeploymentNode as BasePromptDeploymentNode
|
6
6
|
from vellum.workflows.outputs import BaseOutput
|
7
|
+
from vellum.workflows.types import MergeBehavior
|
7
8
|
from vellum.workflows.types.generics import StateType
|
8
9
|
|
9
10
|
|
@@ -23,6 +24,9 @@ class PromptDeploymentNode(BasePromptDeploymentNode[StateType]):
|
|
23
24
|
request_options: Optional[RequestOptions] - The request options to use for the Prompt Execution
|
24
25
|
"""
|
25
26
|
|
27
|
+
class Trigger(BasePromptDeploymentNode.Trigger):
|
28
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
29
|
+
|
26
30
|
class Outputs(BasePromptDeploymentNode.Outputs):
|
27
31
|
"""
|
28
32
|
The outputs of the PromptDeploymentNode.
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import ClassVar
|
2
2
|
|
3
3
|
from vellum.workflows.nodes.displayable.bases import BaseSearchNode as BaseSearchNode
|
4
|
+
from vellum.workflows.types import MergeBehavior
|
4
5
|
from vellum.workflows.types.generics import StateType
|
5
6
|
|
6
7
|
|
@@ -18,6 +19,9 @@ class SearchNode(BaseSearchNode[StateType]):
|
|
18
19
|
|
19
20
|
chunk_separator: ClassVar[str] = "\n\n#####\n\n"
|
20
21
|
|
22
|
+
class Trigger(BaseSearchNode.Trigger):
|
23
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
24
|
+
|
21
25
|
class Outputs(BaseSearchNode.Outputs):
|
22
26
|
"""
|
23
27
|
The outputs of the SearchNode.
|
@@ -19,7 +19,7 @@ from vellum.workflows.errors.types import workflow_event_error_to_workflow_error
|
|
19
19
|
from vellum.workflows.exceptions import NodeException
|
20
20
|
from vellum.workflows.nodes.bases.base import BaseNode
|
21
21
|
from vellum.workflows.outputs.base import BaseOutput
|
22
|
-
from vellum.workflows.types.core import EntityInputsInterface
|
22
|
+
from vellum.workflows.types.core import EntityInputsInterface, MergeBehavior
|
23
23
|
from vellum.workflows.types.generics import StateType
|
24
24
|
|
25
25
|
|
@@ -49,6 +49,9 @@ class SubworkflowDeploymentNode(BaseNode[StateType], Generic[StateType]):
|
|
49
49
|
|
50
50
|
request_options: Optional[RequestOptions] = None
|
51
51
|
|
52
|
+
class Trigger(BaseNode.Trigger):
|
53
|
+
merge_behavior = MergeBehavior.AWAIT_ANY
|
54
|
+
|
52
55
|
def _compile_subworkflow_inputs(self) -> List[WorkflowRequestInputRequest]:
|
53
56
|
# TODO: We may want to consolidate with prompt deployment input compilation
|
54
57
|
# https://app.shortcut.com/vellum/story/4117
|