vellum-ai 0.13.20__py3-none-any.whl → 0.13.21__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/events/workflow.py +7 -7
- vellum/workflows/graph/graph.py +6 -0
- vellum/workflows/graph/tests/test_graph.py +24 -0
- vellum/workflows/nodes/bases/base.py +3 -2
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py +5 -5
- vellum/workflows/runner/runner.py +3 -3
- vellum/workflows/types/generics.py +1 -1
- vellum/workflows/workflows/base.py +11 -11
- {vellum_ai-0.13.20.dist-info → vellum_ai-0.13.21.dist-info}/METADATA +1 -1
- {vellum_ai-0.13.20.dist-info → vellum_ai-0.13.21.dist-info}/RECORD +17 -16
- vellum_ee/workflows/display/utils/vellum.py +7 -0
- vellum_ee/workflows/display/workflows/tests/test_workflow_display.py +65 -0
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py +10 -7
- {vellum_ai-0.13.20.dist-info → vellum_ai-0.13.21.dist-info}/LICENSE +0 -0
- {vellum_ai-0.13.20.dist-info → vellum_ai-0.13.21.dist-info}/WHEEL +0 -0
- {vellum_ai-0.13.20.dist-info → vellum_ai-0.13.21.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.21",
|
22
22
|
}
|
23
23
|
headers["X_API_KEY"] = self.api_key
|
24
24
|
return headers
|
@@ -6,7 +6,7 @@ from vellum.core.pydantic_utilities import UniversalBaseModel
|
|
6
6
|
from vellum.workflows.errors import WorkflowError
|
7
7
|
from vellum.workflows.outputs.base import BaseOutput
|
8
8
|
from vellum.workflows.references import ExternalInputReference
|
9
|
-
from vellum.workflows.types.generics import OutputsType, StateType
|
9
|
+
from vellum.workflows.types.generics import InputsType, OutputsType, StateType
|
10
10
|
|
11
11
|
from .node import (
|
12
12
|
NodeExecutionFulfilledEvent,
|
@@ -38,20 +38,20 @@ class _BaseWorkflowEvent(BaseEvent):
|
|
38
38
|
return self.body.workflow_definition
|
39
39
|
|
40
40
|
|
41
|
-
class WorkflowExecutionInitiatedBody(_BaseWorkflowExecutionBody, Generic[
|
42
|
-
inputs:
|
41
|
+
class WorkflowExecutionInitiatedBody(_BaseWorkflowExecutionBody, Generic[InputsType]):
|
42
|
+
inputs: InputsType
|
43
43
|
|
44
44
|
@field_serializer("inputs")
|
45
|
-
def serialize_inputs(self, inputs:
|
45
|
+
def serialize_inputs(self, inputs: InputsType, _info: Any) -> Dict[str, Any]:
|
46
46
|
return default_serializer(inputs)
|
47
47
|
|
48
48
|
|
49
|
-
class WorkflowExecutionInitiatedEvent(_BaseWorkflowEvent, Generic[
|
49
|
+
class WorkflowExecutionInitiatedEvent(_BaseWorkflowEvent, Generic[InputsType]):
|
50
50
|
name: Literal["workflow.execution.initiated"] = "workflow.execution.initiated"
|
51
|
-
body: WorkflowExecutionInitiatedBody[
|
51
|
+
body: WorkflowExecutionInitiatedBody[InputsType]
|
52
52
|
|
53
53
|
@property
|
54
|
-
def inputs(self) ->
|
54
|
+
def inputs(self) -> InputsType:
|
55
55
|
return self.body.inputs
|
56
56
|
|
57
57
|
|
vellum/workflows/graph/graph.py
CHANGED
@@ -118,6 +118,12 @@ class Graph:
|
|
118
118
|
self._terminals = {other}
|
119
119
|
return self
|
120
120
|
|
121
|
+
def __rrshift__(cls, other_cls: GraphTarget) -> "Graph":
|
122
|
+
if not isinstance(other_cls, set):
|
123
|
+
other_cls = {other_cls}
|
124
|
+
|
125
|
+
return Graph.from_set(other_cls) >> cls
|
126
|
+
|
121
127
|
@property
|
122
128
|
def entrypoints(self) -> Iterator[Type["BaseNode"]]:
|
123
129
|
return iter(e.node_class for e in self._entrypoints)
|
@@ -460,3 +460,27 @@ def test_graph__node_to_port():
|
|
460
460
|
|
461
461
|
# AND two edges
|
462
462
|
assert len(list(graph.edges)) == 2
|
463
|
+
|
464
|
+
|
465
|
+
def test_graph__set_to_graph():
|
466
|
+
# GIVEN three nodes
|
467
|
+
class SourceNode(BaseNode):
|
468
|
+
pass
|
469
|
+
|
470
|
+
class MiddleNode(BaseNode):
|
471
|
+
pass
|
472
|
+
|
473
|
+
class TargetNode(BaseNode):
|
474
|
+
pass
|
475
|
+
|
476
|
+
# WHEN we create a graph from a set to a graph
|
477
|
+
graph: Graph = {SourceNode, MiddleNode} >> Graph.from_node(TargetNode)
|
478
|
+
|
479
|
+
# THEN the graph has the source node and middle node as the entrypoints
|
480
|
+
assert set(graph.entrypoints) == {SourceNode, MiddleNode}
|
481
|
+
|
482
|
+
# AND three nodes
|
483
|
+
assert len(list(graph.nodes)) == 3
|
484
|
+
|
485
|
+
# AND two edges
|
486
|
+
assert len(list(graph.edges)) == 2
|
@@ -1,3 +1,4 @@
|
|
1
|
+
from dataclasses import field
|
1
2
|
from functools import cached_property, reduce
|
2
3
|
import inspect
|
3
4
|
from types import MappingProxyType
|
@@ -192,7 +193,7 @@ class _BaseNodeTriggerMeta(type):
|
|
192
193
|
|
193
194
|
class _BaseNodeExecutionMeta(type):
|
194
195
|
def __getattribute__(cls, name: str) -> Any:
|
195
|
-
if name
|
196
|
+
if name == "count" and issubclass(cls, BaseNode.Execution):
|
196
197
|
return ExecutionCountReference(cls.node_class)
|
197
198
|
|
198
199
|
return super().__getattribute__(name)
|
@@ -230,7 +231,7 @@ class BaseNode(Generic[StateType], metaclass=BaseNodeMeta):
|
|
230
231
|
# "Outputs" class inherits from "BaseOutputs" and do so automatically.
|
231
232
|
# https://app.shortcut.com/vellum/story/4008/auto-inherit-basenodeoutputs-in-outputs-classes
|
232
233
|
class Outputs(BaseOutputs):
|
233
|
-
_node_class:
|
234
|
+
_node_class: Type["BaseNode"] = field(init=False)
|
234
235
|
|
235
236
|
class Ports(NodePorts):
|
236
237
|
default = Port(default=True)
|
@@ -11,7 +11,7 @@ from vellum.workflows.references import OutputReference
|
|
11
11
|
from vellum.workflows.state.base import BaseState
|
12
12
|
from vellum.workflows.state.context import WorkflowContext
|
13
13
|
from vellum.workflows.types.core import EntityInputsInterface
|
14
|
-
from vellum.workflows.types.generics import
|
14
|
+
from vellum.workflows.types.generics import InputsType, StateType
|
15
15
|
from vellum.workflows.workflows.event_filters import all_workflow_event_filter
|
16
16
|
|
17
17
|
if TYPE_CHECKING:
|
@@ -57,16 +57,16 @@ class _InlineSubworkflowNodeMeta(BaseNodeMeta):
|
|
57
57
|
|
58
58
|
|
59
59
|
class InlineSubworkflowNode(
|
60
|
-
BaseNode[StateType], Generic[StateType,
|
60
|
+
BaseNode[StateType], Generic[StateType, InputsType, InnerStateType], metaclass=_InlineSubworkflowNodeMeta
|
61
61
|
):
|
62
62
|
"""
|
63
63
|
Used to execute a Subworkflow defined inline.
|
64
64
|
|
65
|
-
subworkflow: Type["BaseWorkflow[
|
65
|
+
subworkflow: Type["BaseWorkflow[InputsType, InnerStateType]"] - The Subworkflow to execute
|
66
66
|
subworkflow_inputs: ClassVar[EntityInputsInterface] = {}
|
67
67
|
"""
|
68
68
|
|
69
|
-
subworkflow: Type["BaseWorkflow[
|
69
|
+
subworkflow: Type["BaseWorkflow[InputsType, InnerStateType]"]
|
70
70
|
subworkflow_inputs: ClassVar[Union[EntityInputsInterface, BaseInputs, Type[UNDEF]]] = UNDEF
|
71
71
|
|
72
72
|
def run(self) -> Iterator[BaseOutput]:
|
@@ -109,7 +109,7 @@ class InlineSubworkflowNode(
|
|
109
109
|
value=output_value,
|
110
110
|
)
|
111
111
|
|
112
|
-
def _compile_subworkflow_inputs(self) ->
|
112
|
+
def _compile_subworkflow_inputs(self) -> InputsType:
|
113
113
|
inputs_class = self.subworkflow.get_inputs_class()
|
114
114
|
if self.subworkflow_inputs is UNDEF:
|
115
115
|
inputs_dict = {}
|
@@ -65,7 +65,7 @@ from vellum.workflows.ports.port import Port
|
|
65
65
|
from vellum.workflows.references import ExternalInputReference, OutputReference
|
66
66
|
from vellum.workflows.state.base import BaseState
|
67
67
|
from vellum.workflows.types.cycle_map import CycleMap
|
68
|
-
from vellum.workflows.types.generics import OutputsType, StateType
|
68
|
+
from vellum.workflows.types.generics import InputsType, OutputsType, StateType
|
69
69
|
|
70
70
|
if TYPE_CHECKING:
|
71
71
|
from vellum.workflows import BaseWorkflow
|
@@ -82,8 +82,8 @@ class WorkflowRunner(Generic[StateType]):
|
|
82
82
|
|
83
83
|
def __init__(
|
84
84
|
self,
|
85
|
-
workflow: "BaseWorkflow[
|
86
|
-
inputs: Optional[
|
85
|
+
workflow: "BaseWorkflow[InputsType, StateType]",
|
86
|
+
inputs: Optional[InputsType] = None,
|
87
87
|
state: Optional[StateType] = None,
|
88
88
|
entrypoint_nodes: Optional[RunFromNodeArg] = None,
|
89
89
|
external_inputs: Optional[ExternalInputsArg] = None,
|
@@ -10,5 +10,5 @@ if TYPE_CHECKING:
|
|
10
10
|
NodeType = TypeVar("NodeType", bound="BaseNode")
|
11
11
|
StateType = TypeVar("StateType", bound="BaseState")
|
12
12
|
WorkflowType = TypeVar("WorkflowType", bound="BaseWorkflow")
|
13
|
-
|
13
|
+
InputsType = TypeVar("InputsType", bound="BaseInputs")
|
14
14
|
OutputsType = TypeVar("OutputsType", bound="BaseOutputs")
|
@@ -68,7 +68,7 @@ from vellum.workflows.runner.runner import ExternalInputsArg, RunFromNodeArg
|
|
68
68
|
from vellum.workflows.state.base import BaseState, StateMeta
|
69
69
|
from vellum.workflows.state.context import WorkflowContext
|
70
70
|
from vellum.workflows.state.store import Store
|
71
|
-
from vellum.workflows.types.generics import
|
71
|
+
from vellum.workflows.types.generics import InputsType, StateType
|
72
72
|
from vellum.workflows.types.utils import get_original_base
|
73
73
|
from vellum.workflows.utils.uuids import uuid4_from_hash
|
74
74
|
from vellum.workflows.workflows.event_filters import workflow_event_filter
|
@@ -88,7 +88,7 @@ class _BaseWorkflowMeta(type):
|
|
88
88
|
GraphAttribute = Union[Type[BaseNode], Graph, Set[Type[BaseNode]], Set[Graph]]
|
89
89
|
|
90
90
|
|
91
|
-
class BaseWorkflow(Generic[
|
91
|
+
class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
|
92
92
|
__id__: UUID = uuid4_from_hash(__qualname__)
|
93
93
|
graph: ClassVar[GraphAttribute]
|
94
94
|
emitters: List[BaseWorkflowEmitter]
|
@@ -99,7 +99,7 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
99
99
|
|
100
100
|
WorkflowEvent = Union[ # type: ignore
|
101
101
|
GenericWorkflowEvent,
|
102
|
-
WorkflowExecutionInitiatedEvent[
|
102
|
+
WorkflowExecutionInitiatedEvent[InputsType], # type: ignore[valid-type]
|
103
103
|
WorkflowExecutionFulfilledEvent[Outputs],
|
104
104
|
WorkflowExecutionSnapshottedEvent[StateType], # type: ignore[valid-type]
|
105
105
|
]
|
@@ -181,7 +181,7 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
181
181
|
|
182
182
|
def run(
|
183
183
|
self,
|
184
|
-
inputs: Optional[
|
184
|
+
inputs: Optional[InputsType] = None,
|
185
185
|
*,
|
186
186
|
state: Optional[StateType] = None,
|
187
187
|
entrypoint_nodes: Optional[RunFromNodeArg] = None,
|
@@ -198,7 +198,7 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
198
198
|
|
199
199
|
Parameters
|
200
200
|
----------
|
201
|
-
inputs: Optional[
|
201
|
+
inputs: Optional[InputsType] = None
|
202
202
|
The Inputs instance used to initiate the Workflow Execution.
|
203
203
|
|
204
204
|
state: Optional[StateType] = None
|
@@ -288,7 +288,7 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
288
288
|
|
289
289
|
def stream(
|
290
290
|
self,
|
291
|
-
inputs: Optional[
|
291
|
+
inputs: Optional[InputsType] = None,
|
292
292
|
*,
|
293
293
|
event_filter: Optional[Callable[[Type["BaseWorkflow"], WorkflowEvent], bool]] = None,
|
294
294
|
state: Optional[StateType] = None,
|
@@ -307,7 +307,7 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
307
307
|
A filter that can be used to filter events based on the Workflow Class and the event itself. If the method
|
308
308
|
returns `False`, the event will not be yielded.
|
309
309
|
|
310
|
-
inputs: Optional[
|
310
|
+
inputs: Optional[InputsType] = None
|
311
311
|
The Inputs instance used to initiate the Workflow Execution.
|
312
312
|
|
313
313
|
state: Optional[StateType] = None
|
@@ -359,7 +359,7 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
359
359
|
@lru_cache
|
360
360
|
def _get_parameterized_classes(
|
361
361
|
cls,
|
362
|
-
) -> Tuple[Type[
|
362
|
+
) -> Tuple[Type[InputsType], Type[StateType]]:
|
363
363
|
original_base = get_original_base(cls)
|
364
364
|
|
365
365
|
inputs_type, state_type = get_args(original_base)
|
@@ -378,17 +378,17 @@ class BaseWorkflow(Generic[WorkflowInputsType, StateType], metaclass=_BaseWorkfl
|
|
378
378
|
return (inputs_type, state_type)
|
379
379
|
|
380
380
|
@classmethod
|
381
|
-
def get_inputs_class(cls) -> Type[
|
381
|
+
def get_inputs_class(cls) -> Type[InputsType]:
|
382
382
|
return cls._get_parameterized_classes()[0]
|
383
383
|
|
384
384
|
@classmethod
|
385
385
|
def get_state_class(cls) -> Type[StateType]:
|
386
386
|
return cls._get_parameterized_classes()[1]
|
387
387
|
|
388
|
-
def get_default_inputs(self) ->
|
388
|
+
def get_default_inputs(self) -> InputsType:
|
389
389
|
return self.get_inputs_class()()
|
390
390
|
|
391
|
-
def get_default_state(self, workflow_inputs: Optional[
|
391
|
+
def get_default_state(self, workflow_inputs: Optional[InputsType] = None) -> StateType:
|
392
392
|
return self.get_state_class()(
|
393
393
|
meta=StateMeta(
|
394
394
|
parent=self._parent_state,
|
@@ -79,12 +79,13 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_ser
|
|
79
79
|
vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py,sha256=xmKyOKqGRhWUXXbTbCAXX40qINcvK7mjpEfXz0Ny21s,7404
|
80
80
|
vellum_ee/workflows/display/types.py,sha256=jWTpfQv3baEWjbP12duc3MBz3TK03Ja1UI5458PVQVY,4211
|
81
81
|
vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
82
|
-
vellum_ee/workflows/display/utils/vellum.py,sha256=
|
82
|
+
vellum_ee/workflows/display/utils/vellum.py,sha256=IGHobHz0QG8TWdJNxlQ81khCmJv7piLjE64l4zc33kI,7743
|
83
83
|
vellum_ee/workflows/display/vellum.py,sha256=-95xvit30nyP6Md29nHkfIrnFButZyCg8wz76oUHD0M,8105
|
84
84
|
vellum_ee/workflows/display/workflows/__init__.py,sha256=kapXsC67VJcgSuiBMa86FdePG5A9kMB5Pi4Uy1O2ob4,207
|
85
85
|
vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=x4C621UTH_SZLJYmVBiC1q-D-wadJlTiSGlKAI6CUbA,14082
|
86
86
|
vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=kp0u8LN_2IwshLrhMImhpZx1hRyAcD5gXY-kDuuaGMQ,1269
|
87
|
-
vellum_ee/workflows/display/workflows/
|
87
|
+
vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=yl1ytpl9_lijOGeDPWSypWYRJ7aOEVA7NgUg81jTuCs,2229
|
88
|
+
vellum_ee/workflows/display/workflows/vellum_workflow_display.py,sha256=IiHfMglir81cwPFYnwvgynp79cgzFyYVkMJAABIi3BQ,17035
|
88
89
|
vellum_ee/workflows/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
89
90
|
vellum_ee/workflows/server/virtual_file_loader.py,sha256=X_DdNK7MfyOjKWekk6YQpOSCT6klKcdjT6nVJcBH1sM,1481
|
90
91
|
vellum_ee/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -113,7 +114,7 @@ vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
|
|
113
114
|
vellum/client/__init__.py,sha256=8nZt88C9SVwWanjLbIQMU3rzb32h5UZfFMBx3VPHB50,111887
|
114
115
|
vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
|
115
116
|
vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
|
116
|
-
vellum/client/core/client_wrapper.py,sha256=
|
117
|
+
vellum/client/core/client_wrapper.py,sha256=5SwzGdamiAC-bG69Fab06ulKRPF_5B1kp_GF6a4fr3g,1869
|
117
118
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
118
119
|
vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
|
119
120
|
vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
|
@@ -1269,7 +1270,7 @@ vellum/workflows/events/node.py,sha256=uHT6If0esgZ3nLjrjmUPTKf3qbjGhoV_x5YKpjDBD
|
|
1269
1270
|
vellum/workflows/events/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1270
1271
|
vellum/workflows/events/tests/test_event.py,sha256=9rbp92dQXpGFad-LjE2nYU17neKkiHxQz9X8RsoCWs4,13718
|
1271
1272
|
vellum/workflows/events/types.py,sha256=cjRE8WL8tYCFradd9NOGl_H0mN3LiWWnA1uHmyT2Q0Q,3412
|
1272
|
-
vellum/workflows/events/workflow.py,sha256=
|
1273
|
+
vellum/workflows/events/workflow.py,sha256=lveoWXtVRLjdO_nu0z6VlKeTqlGimogamiFR-jYihlE,5184
|
1273
1274
|
vellum/workflows/exceptions.py,sha256=l-FLGvXywxg6ivolCts71b8pcsYAWoB1cmUR4Jx7N8g,614
|
1274
1275
|
vellum/workflows/expressions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1275
1276
|
vellum/workflows/expressions/accessor.py,sha256=daIkEudAdyiqCOzO9x_3cy-Y9ilYgNWSEeqcFelkjI0,1743
|
@@ -1301,15 +1302,15 @@ vellum/workflows/expressions/not_between.py,sha256=H2huRR95D9Qb7lCHmK7BcK-Ug-E1g
|
|
1301
1302
|
vellum/workflows/expressions/not_in.py,sha256=OQkN5G1E6VoTDpoLvx7X3GbohLlqEAYHV0rVVUV7ow4,1049
|
1302
1303
|
vellum/workflows/expressions/or_.py,sha256=s-8YdMSSCDS2yijR38kguwok3iqmDMMgDYKV93b4O4s,914
|
1303
1304
|
vellum/workflows/graph/__init__.py,sha256=3sHlay5d_-uD7j3QJXiGl0WHFZZ_QScRvgyDhN2GhHY,74
|
1304
|
-
vellum/workflows/graph/graph.py,sha256=
|
1305
|
+
vellum/workflows/graph/graph.py,sha256=GGR8cGpSuNWPIiTWNWsj6l70upb5nIxAyFcn7VdaJIs,5506
|
1305
1306
|
vellum/workflows/graph/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1306
|
-
vellum/workflows/graph/tests/test_graph.py,sha256=
|
1307
|
+
vellum/workflows/graph/tests/test_graph.py,sha256=q0wxLvPPxc-6en4a_XuAZwVfLURMd9Ikvoreq4bpJ9s,11839
|
1307
1308
|
vellum/workflows/inputs/__init__.py,sha256=AbFEteIYEvCb14fM3EK7bhM-40-6s494rSlIhQ4Dsss,62
|
1308
1309
|
vellum/workflows/inputs/base.py,sha256=1kMgr0WqCYdWUqgFvgSoAMw2067FAlgwhGXLgbIOrLY,2391
|
1309
1310
|
vellum/workflows/logging.py,sha256=_a217XogktV4Ncz6xKFz7WfYmZAzkfVRVuC0rWob8ls,437
|
1310
1311
|
vellum/workflows/nodes/__init__.py,sha256=aVdQVv7Y3Ro3JlqXGpxwaU2zrI06plDHD2aumH5WUIs,1157
|
1311
1312
|
vellum/workflows/nodes/bases/__init__.py,sha256=cniHuz_RXdJ4TQgD8CBzoiKDiPxg62ErdVpCbWICX64,58
|
1312
|
-
vellum/workflows/nodes/bases/base.py,sha256=
|
1313
|
+
vellum/workflows/nodes/bases/base.py,sha256=v6Y38xRTTKQxfvDpnx7X37EQN6Mrxu2vKtMDQiR2g8A,14186
|
1313
1314
|
vellum/workflows/nodes/bases/base_adornment_node.py,sha256=eFTgsPCYb3eyGS0-kw7C6crFnwFx437R5wh9-8bWYts,2905
|
1314
1315
|
vellum/workflows/nodes/bases/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1315
1316
|
vellum/workflows/nodes/bases/tests/test_base_node.py,sha256=51CueFVty9XYASC0rKr1cXWejho5WElmhfhp6cCONy0,3811
|
@@ -1317,7 +1318,7 @@ vellum/workflows/nodes/core/__init__.py,sha256=5zDMCmyt1v0HTJzlUBwq3U9L825yZGZhT
|
|
1317
1318
|
vellum/workflows/nodes/core/error_node/__init__.py,sha256=g7RRnlHhqu4qByfLjBwCunmgGA8dI5gNsjS3h6TwlSI,60
|
1318
1319
|
vellum/workflows/nodes/core/error_node/node.py,sha256=MFHU5vITYSK-L9CuMZ49In2ZeNLWnhZD0f8r5dWvb5Y,1270
|
1319
1320
|
vellum/workflows/nodes/core/inline_subworkflow_node/__init__.py,sha256=nKNEH1QTl-1PcvmYoqSWEl0-t6gAur8GLTXHzklRQfM,84
|
1320
|
-
vellum/workflows/nodes/core/inline_subworkflow_node/node.py,sha256=
|
1321
|
+
vellum/workflows/nodes/core/inline_subworkflow_node/node.py,sha256=yOVuY-J2IHCdOwt9VriSZwBRngB9MlFzmAmehqXMqlo,5891
|
1321
1322
|
vellum/workflows/nodes/core/inline_subworkflow_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1322
1323
|
vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py,sha256=n0-821Ov9ZfRFX_lbzLy5o2rX8fEw2qoxz0aFWCOxVg,1547
|
1323
1324
|
vellum/workflows/nodes/core/map_node/__init__.py,sha256=MXpZYmGfhsMJHqqlpd64WiJRtbAtAMQz-_3fCU_cLV0,56
|
@@ -1411,7 +1412,7 @@ vellum/workflows/references/workflow_input.py,sha256=86IuhlBz-9cGxeUzizyjdp482aj
|
|
1411
1412
|
vellum/workflows/resolvers/__init__.py,sha256=eH6hTvZO4IciDaf_cf7aM2vs-DkBDyJPycOQevJxQnI,82
|
1412
1413
|
vellum/workflows/resolvers/base.py,sha256=WHra9LRtlTuB1jmuNqkfVE2JUgB61Cyntn8f0b0WZg4,411
|
1413
1414
|
vellum/workflows/runner/__init__.py,sha256=i1iG5sAhtpdsrlvwgH6B-m49JsINkiWyPWs8vyT-bqM,72
|
1414
|
-
vellum/workflows/runner/runner.py,sha256=
|
1415
|
+
vellum/workflows/runner/runner.py,sha256=vGd5yfx4udwvGHkbFElDtsre__3JD8zIqhx6ZreRwN4,29172
|
1415
1416
|
vellum/workflows/sandbox.py,sha256=GVJzVjMuYzOBnSrboB0_6MMRZWBluAyQ2o7syeaeBd0,2235
|
1416
1417
|
vellum/workflows/state/__init__.py,sha256=yUUdR-_Vl7UiixNDYQZ-GEM_kJI9dnOia75TtuNEsnE,60
|
1417
1418
|
vellum/workflows/state/base.py,sha256=IIl76sJtn0GfbFWBqMnpGuvtZyVyQMEXv0QKDfLy8Wg,14763
|
@@ -1425,7 +1426,7 @@ vellum/workflows/tests/test_sandbox.py,sha256=JKwaluI-lODQo7Ek9sjDstjL_WTdSqUlVi
|
|
1425
1426
|
vellum/workflows/types/__init__.py,sha256=KxUTMBGzuRCfiMqzzsykOeVvrrkaZmTTo1a7SLu8gRM,68
|
1426
1427
|
vellum/workflows/types/core.py,sha256=kMQremh_I8egXpiKmtMQbB6e3OczAWiRnnTq5V6xlD0,928
|
1427
1428
|
vellum/workflows/types/cycle_map.py,sha256=-ZMQsKzZBpCi0bchJrkuN_dtCFuz9uFABy7Fq2PI58E,928
|
1428
|
-
vellum/workflows/types/generics.py,sha256=
|
1429
|
+
vellum/workflows/types/generics.py,sha256=9HzFvtcF8qpn1wcsly7er250MMwdS9r-BjSVco9UBj4,584
|
1429
1430
|
vellum/workflows/types/stack.py,sha256=RDSGLkcV612ge8UuAH9TZiEGXxJt0Av2-H5rfzrTVVI,1014
|
1430
1431
|
vellum/workflows/types/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1431
1432
|
vellum/workflows/types/tests/test_utils.py,sha256=y2bj4O8-ykPRRRocdD98NdnQz6ydSCoMBp6rECPPqE8,2536
|
@@ -1442,10 +1443,10 @@ vellum/workflows/utils/uuids.py,sha256=DFzPv9RCvsKhvdTEIQyfSek2A31D6S_QcmeLPbgrg
|
|
1442
1443
|
vellum/workflows/utils/vellum_variables.py,sha256=g5xHYB8etfHE32ek19nP6Anf8NyjhmUtOwO2KmQ5xZU,3111
|
1443
1444
|
vellum/workflows/vellum_client.py,sha256=ODrq_TSl-drX2aezXegf7pizpWDVJuTXH-j6528t75s,683
|
1444
1445
|
vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
|
1445
|
-
vellum/workflows/workflows/base.py,sha256=
|
1446
|
+
vellum/workflows/workflows/base.py,sha256=kL4lxTdhaupw58sqzCutI5K8tDSfk2gHXDddCrg6FGA,18265
|
1446
1447
|
vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
|
1447
|
-
vellum_ai-0.13.
|
1448
|
-
vellum_ai-0.13.
|
1449
|
-
vellum_ai-0.13.
|
1450
|
-
vellum_ai-0.13.
|
1451
|
-
vellum_ai-0.13.
|
1448
|
+
vellum_ai-0.13.21.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
1449
|
+
vellum_ai-0.13.21.dist-info/METADATA,sha256=DVUX-LtxUw5KFTUz0NzF92v-sCkAczyHJ9zDeDfD3og,5335
|
1450
|
+
vellum_ai-0.13.21.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
1451
|
+
vellum_ai-0.13.21.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
|
1452
|
+
vellum_ai-0.13.21.dist-info/RECORD,,
|
@@ -28,6 +28,7 @@ from vellum.workflows.expressions.less_than_or_equal_to import LessThanOrEqualTo
|
|
28
28
|
from vellum.workflows.expressions.not_between import NotBetweenExpression
|
29
29
|
from vellum.workflows.expressions.not_in import NotInExpression
|
30
30
|
from vellum.workflows.expressions.or_ import OrExpression
|
31
|
+
from vellum.workflows.nodes.bases.base import BaseNode
|
31
32
|
from vellum.workflows.nodes.displayable.bases.utils import primitive_to_vellum_value
|
32
33
|
from vellum.workflows.references import OutputReference, WorkflowInputReference
|
33
34
|
from vellum.workflows.references.execution_count import ExecutionCountReference
|
@@ -76,6 +77,12 @@ def create_node_input_value_pointer_rule(
|
|
76
77
|
value: Any, display_context: "WorkflowDisplayContext"
|
77
78
|
) -> NodeInputValuePointerRule:
|
78
79
|
if isinstance(value, OutputReference):
|
80
|
+
if value not in display_context.global_node_output_displays:
|
81
|
+
if issubclass(value.outputs_class, BaseNode.Outputs):
|
82
|
+
raise ValueError(f"Reference to node '{value.outputs_class._node_class.__name__}' not found in graph.")
|
83
|
+
|
84
|
+
raise ValueError(f"Reference to outputs '{value.outputs_class.__qualname__}' is invalid.")
|
85
|
+
|
79
86
|
upstream_node, output_display = display_context.global_node_output_displays[value]
|
80
87
|
upstream_node_display = display_context.global_node_displays[upstream_node]
|
81
88
|
return NodeOutputPointer(
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from vellum.workflows.nodes.bases.base import BaseNode
|
4
|
+
from vellum.workflows.workflows.base import BaseWorkflow
|
5
|
+
from vellum_ee.workflows.display.workflows import VellumWorkflowDisplay
|
6
|
+
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
7
|
+
|
8
|
+
|
9
|
+
def test_serialize_workflow__node_referenced_in_workflow_outputs_not_in_graph():
|
10
|
+
# GIVEN a couple of nodes
|
11
|
+
class InNode(BaseNode):
|
12
|
+
pass
|
13
|
+
|
14
|
+
class OutNode(BaseNode):
|
15
|
+
class Outputs(BaseNode.Outputs):
|
16
|
+
foo: str
|
17
|
+
|
18
|
+
# AND A workflow that references the OutNode in its outputs but only has the InNode in its graph
|
19
|
+
class Workflow(BaseWorkflow):
|
20
|
+
graph = InNode
|
21
|
+
|
22
|
+
class Outputs(BaseWorkflow.Outputs):
|
23
|
+
final = OutNode.Outputs.foo
|
24
|
+
|
25
|
+
# WHEN we serialize it
|
26
|
+
workflow_display = get_workflow_display(
|
27
|
+
base_display_class=VellumWorkflowDisplay,
|
28
|
+
workflow_class=Workflow,
|
29
|
+
)
|
30
|
+
|
31
|
+
# THEN it should raise an error
|
32
|
+
with pytest.raises(ValueError) as exc_info:
|
33
|
+
workflow_display.serialize()
|
34
|
+
|
35
|
+
# AND the error message should be user friendly
|
36
|
+
assert str(exc_info.value) == "Failed to serialize output 'final': Reference to node 'OutNode' not found in graph."
|
37
|
+
|
38
|
+
|
39
|
+
def test_serialize_workflow__workflow_outputs_reference_non_node_outputs():
|
40
|
+
# GIVEN one Workflow
|
41
|
+
class FirstWorkflow(BaseWorkflow):
|
42
|
+
class Outputs(BaseWorkflow.Outputs):
|
43
|
+
foo = "bar"
|
44
|
+
|
45
|
+
# AND A workflow that references the Outputs of that Workflow
|
46
|
+
class Workflow(BaseWorkflow):
|
47
|
+
class Outputs(BaseWorkflow.Outputs):
|
48
|
+
final = FirstWorkflow.Outputs.foo
|
49
|
+
|
50
|
+
# WHEN we serialize it
|
51
|
+
workflow_display = get_workflow_display(
|
52
|
+
base_display_class=VellumWorkflowDisplay,
|
53
|
+
workflow_class=Workflow,
|
54
|
+
)
|
55
|
+
|
56
|
+
# THEN it should raise an error
|
57
|
+
with pytest.raises(ValueError) as exc_info:
|
58
|
+
workflow_display.serialize()
|
59
|
+
|
60
|
+
# AND the error message should be user friendly
|
61
|
+
assert (
|
62
|
+
str(exc_info.value)
|
63
|
+
== """Failed to serialize output 'final': Reference to outputs \
|
64
|
+
'test_serialize_workflow__workflow_outputs_reference_non_node_outputs.<locals>.FirstWorkflow.Outputs' is invalid."""
|
65
|
+
)
|
@@ -129,13 +129,16 @@ class VellumWorkflowDisplay(
|
|
129
129
|
|
130
130
|
if workflow_output.instance not in final_output_node_outputs:
|
131
131
|
# Create a synthetic terminal node only if there is no terminal node for this output
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
132
|
+
try:
|
133
|
+
node_input = create_node_input(
|
134
|
+
final_output_node_id,
|
135
|
+
"node_input",
|
136
|
+
# This is currently the wrapper node's output, but we want the wrapped node
|
137
|
+
workflow_output.instance,
|
138
|
+
self.display_context,
|
139
|
+
)
|
140
|
+
except ValueError as e:
|
141
|
+
raise ValueError(f"Failed to serialize output '{workflow_output.name}': {str(e)}") from e
|
139
142
|
|
140
143
|
source_node_display: Optional[BaseNodeDisplay]
|
141
144
|
first_rule = node_input.value.rules[0]
|
File without changes
|
File without changes
|
File without changes
|