vellum-ai 1.3.5__py3-none-any.whl → 1.3.6__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/README.md +16 -0
- vellum/client/core/client_wrapper.py +2 -2
- vellum/plugins/vellum_mypy.py +12 -9
- vellum/workflows/executable.py +9 -0
- vellum/workflows/graph/graph.py +5 -0
- vellum/workflows/graph/tests/test_graph.py +17 -0
- vellum/workflows/nodes/bases/base.py +2 -3
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +9 -2
- vellum/workflows/nodes/displayable/tool_calling_node/node.py +2 -0
- vellum/workflows/nodes/displayable/tool_calling_node/utils.py +7 -1
- vellum/workflows/outputs/base.py +14 -5
- vellum/workflows/references/output.py +1 -1
- vellum/workflows/utils/names.py +12 -4
- vellum/workflows/utils/tests/test_names.py +9 -0
- vellum/workflows/workflows/base.py +3 -5
- {vellum_ai-1.3.5.dist-info → vellum_ai-1.3.6.dist-info}/METADATA +1 -1
- {vellum_ai-1.3.5.dist-info → vellum_ai-1.3.6.dist-info}/RECORD +25 -24
- vellum_ee/workflows/display/nodes/tests/test_base_node_display.py +17 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +1 -1
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_parent_input.py +5 -1
- vellum_ee/workflows/display/utils/expressions.py +35 -14
- vellum_ee/workflows/display/workflows/base_workflow_display.py +3 -9
- {vellum_ai-1.3.5.dist-info → vellum_ai-1.3.6.dist-info}/LICENSE +0 -0
- {vellum_ai-1.3.5.dist-info → vellum_ai-1.3.6.dist-info}/WHEEL +0 -0
- {vellum_ai-1.3.5.dist-info → vellum_ai-1.3.6.dist-info}/entry_points.txt +0 -0
vellum/client/README.md
CHANGED
@@ -232,3 +232,19 @@ client = Vellum(
|
|
232
232
|
)
|
233
233
|
```
|
234
234
|
|
235
|
+
## Contributing
|
236
|
+
|
237
|
+
While we value open-source contributions to this SDK, this library is generated programmatically.
|
238
|
+
Additions made directly to this library would have to be moved over to our generation code,
|
239
|
+
otherwise they would be overwritten upon the next generated release. Feel free to open a PR as
|
240
|
+
a proof of concept, but know that we will not be able to merge it as-is. We suggest opening
|
241
|
+
an issue first to discuss with us!
|
242
|
+
|
243
|
+
On the other hand, contributions to the README are always very welcome!
|
244
|
+
## Open-Source vs. Paid
|
245
|
+
|
246
|
+
This repo is available under the [MIT expat license](https://github.com/vellum-ai/vellum-python-sdks/blob/main/LICENSE), except
|
247
|
+
for the `ee` directory (which has its [license here](https://github.com/vellum-ai/vellum-python-sdks/blob/main/ee/LICENSE)) if applicable.
|
248
|
+
|
249
|
+
To learn more, [book a demo](https://www.vellum.ai/landing-pages/request-demo) or see our [pricing page](https://www.vellum.ai/pricing).
|
250
|
+
|
@@ -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.3.
|
30
|
+
"User-Agent": "vellum-ai/1.3.6",
|
31
31
|
"X-Fern-Language": "Python",
|
32
32
|
"X-Fern-SDK-Name": "vellum-ai",
|
33
|
-
"X-Fern-SDK-Version": "1.3.
|
33
|
+
"X-Fern-SDK-Version": "1.3.6",
|
34
34
|
**(self.get_custom_headers() or {}),
|
35
35
|
}
|
36
36
|
if self._api_version is not None:
|
vellum/plugins/vellum_mypy.py
CHANGED
@@ -20,6 +20,7 @@ from mypy.types import AnyType, CallableType, FunctionLike, Instance, Type as My
|
|
20
20
|
|
21
21
|
TypeResolver = Callable[[str, List[MypyType]], MypyType]
|
22
22
|
NODE_ATTRIBUTE_REGEX = r"^[a-z].*$"
|
23
|
+
BASE_NODE_FULLNAME = "vellum.workflows.nodes.bases.base.BaseNode"
|
23
24
|
|
24
25
|
DESCRIPTOR_PATHS: list[tuple[str, str, str]] = [
|
25
26
|
(
|
@@ -28,12 +29,12 @@ DESCRIPTOR_PATHS: list[tuple[str, str, str]] = [
|
|
28
29
|
r"^[^_].*$",
|
29
30
|
),
|
30
31
|
(
|
31
|
-
"
|
32
|
+
f"{BASE_NODE_FULLNAME}.ExternalInputs",
|
32
33
|
"vellum.workflows.references.external_input.ExternalInputReference",
|
33
34
|
r"^[^_].*$",
|
34
35
|
),
|
35
36
|
(
|
36
|
-
"
|
37
|
+
f"{BASE_NODE_FULLNAME}.Execution",
|
37
38
|
"vellum.workflows.references.execution_count.ExecutionCountReference",
|
38
39
|
r"^count$",
|
39
40
|
),
|
@@ -48,7 +49,7 @@ DESCRIPTOR_PATHS: list[tuple[str, str, str]] = [
|
|
48
49
|
r"^[^_].*$",
|
49
50
|
),
|
50
51
|
(
|
51
|
-
|
52
|
+
BASE_NODE_FULLNAME,
|
52
53
|
"vellum.workflows.references.node.NodeReference",
|
53
54
|
NODE_ATTRIBUTE_REGEX,
|
54
55
|
),
|
@@ -163,7 +164,7 @@ class VellumMypyPlugin(Plugin):
|
|
163
164
|
elif _is_subclass(ctx.cls.info, "vellum.workflows.nodes.displayable.final_output_node.node.FinalOutputNode"):
|
164
165
|
self._dynamic_output_node_class_hook(ctx, "value")
|
165
166
|
|
166
|
-
if _is_subclass(ctx.cls.info,
|
167
|
+
if _is_subclass(ctx.cls.info, BASE_NODE_FULLNAME):
|
167
168
|
return self._base_node_class_hook(ctx)
|
168
169
|
|
169
170
|
if _is_subclass(ctx.cls.info, "vellum.workflows.workflows.base.BaseWorkflow"):
|
@@ -241,6 +242,9 @@ class VellumMypyPlugin(Plugin):
|
|
241
242
|
"""
|
242
243
|
|
243
244
|
for key, sym in ctx.cls.info.names.items():
|
245
|
+
if ctx.cls.info.fullname == BASE_NODE_FULLNAME:
|
246
|
+
continue
|
247
|
+
|
244
248
|
if not isinstance(sym.node, Var):
|
245
249
|
continue
|
246
250
|
|
@@ -250,6 +254,7 @@ class VellumMypyPlugin(Plugin):
|
|
250
254
|
type_ = sym.node.type
|
251
255
|
if not type_:
|
252
256
|
continue
|
257
|
+
|
253
258
|
sym.node.type = self._get_resolvable_type(
|
254
259
|
lambda fullname, types: ctx.api.named_type(fullname, types), type_
|
255
260
|
)
|
@@ -301,7 +306,7 @@ class VellumMypyPlugin(Plugin):
|
|
301
306
|
and isinstance(arg.expr, MemberExpr)
|
302
307
|
and isinstance(arg.expr.expr, NameExpr)
|
303
308
|
and isinstance(arg.expr.expr.node, TypeInfo)
|
304
|
-
and _is_subclass(arg.expr.expr.node,
|
309
|
+
and _is_subclass(arg.expr.expr.node, BASE_NODE_FULLNAME)
|
305
310
|
and arg.expr.name == "Outputs"
|
306
311
|
):
|
307
312
|
self._calls_with_nested_descriptor_expressions.add(call_expr)
|
@@ -548,7 +553,7 @@ class VellumMypyPlugin(Plugin):
|
|
548
553
|
if not isinstance(ctx.default_return_type, Instance):
|
549
554
|
return ctx.default_return_type
|
550
555
|
|
551
|
-
if not _is_subclass(ctx.default_return_type.type, "
|
556
|
+
if not _is_subclass(ctx.default_return_type.type, f"{BASE_NODE_FULLNAME}.Outputs"):
|
552
557
|
return ctx.default_return_type
|
553
558
|
|
554
559
|
outputs_node = self._get_node_outputs_type_info(ctx)
|
@@ -677,9 +682,7 @@ class VellumMypyPlugin(Plugin):
|
|
677
682
|
|
678
683
|
expr = ctx.context.callee.expr
|
679
684
|
instance = ctx.api.get_expression_type(expr)
|
680
|
-
if not isinstance(instance, Instance) or not _is_subclass(
|
681
|
-
instance.type, "vellum.workflows.nodes.bases.base.BaseNode"
|
682
|
-
):
|
685
|
+
if not isinstance(instance, Instance) or not _is_subclass(instance.type, BASE_NODE_FULLNAME):
|
683
686
|
return None
|
684
687
|
|
685
688
|
outputs_node = instance.type.names.get("Outputs")
|
vellum/workflows/graph/graph.py
CHANGED
@@ -96,6 +96,11 @@ class Graph:
|
|
96
96
|
def from_edge(edge: Edge) -> "Graph":
|
97
97
|
return Graph(entrypoints={edge.from_port}, edges=[edge], terminals={port for port in edge.to_node.Ports})
|
98
98
|
|
99
|
+
@staticmethod
|
100
|
+
def empty() -> "Graph":
|
101
|
+
"""Create an empty graph with no entrypoints, edges, or terminals."""
|
102
|
+
return Graph(entrypoints=set(), edges=[], terminals=set())
|
103
|
+
|
99
104
|
def __rshift__(self, other: GraphTarget) -> "Graph":
|
100
105
|
if not self._edges and not self._entrypoints:
|
101
106
|
raise ValueError("Graph instance can only create new edges from nodes within existing edges")
|
@@ -4,6 +4,23 @@ from vellum.workflows.nodes.bases.base import BaseNode
|
|
4
4
|
from vellum.workflows.ports.port import Port
|
5
5
|
|
6
6
|
|
7
|
+
def test_graph__empty():
|
8
|
+
# WHEN we create an empty graph
|
9
|
+
graph = Graph.empty()
|
10
|
+
|
11
|
+
# THEN the graph has no entrypoints
|
12
|
+
assert len(list(graph.entrypoints)) == 0
|
13
|
+
|
14
|
+
# AND no nodes
|
15
|
+
assert len(list(graph.nodes)) == 0
|
16
|
+
|
17
|
+
# AND no edges
|
18
|
+
assert len(list(graph.edges)) == 0
|
19
|
+
|
20
|
+
# AND string representation indicates empty graph
|
21
|
+
assert str(graph) == "Graph(empty)"
|
22
|
+
|
23
|
+
|
7
24
|
def test_graph__from_node():
|
8
25
|
# GIVEN a node
|
9
26
|
class MyNode(BaseNode):
|
@@ -13,6 +13,7 @@ from vellum.workflows.descriptors.utils import is_unresolved, resolve_value
|
|
13
13
|
from vellum.workflows.errors.types import WorkflowErrorCode
|
14
14
|
from vellum.workflows.events.node import NodeExecutionStreamingEvent
|
15
15
|
from vellum.workflows.exceptions import NodeException
|
16
|
+
from vellum.workflows.executable import BaseExecutable
|
16
17
|
from vellum.workflows.graph import Graph
|
17
18
|
from vellum.workflows.graph.graph import GraphTarget
|
18
19
|
from vellum.workflows.inputs.base import BaseInputs
|
@@ -260,9 +261,7 @@ class _BaseNodeExecutionMeta(type):
|
|
260
261
|
NodeRunResponse = Union[BaseOutputs, Iterator[BaseOutput]]
|
261
262
|
|
262
263
|
|
263
|
-
class BaseNode(Generic[StateType], ABC, metaclass=BaseNodeMeta):
|
264
|
-
__id__: UUID = uuid4_from_hash(__qualname__)
|
265
|
-
__output_ids__: Dict[str, UUID] = {}
|
264
|
+
class BaseNode(Generic[StateType], ABC, BaseExecutable, metaclass=BaseNodeMeta):
|
266
265
|
state: StateType
|
267
266
|
_context: WorkflowContext
|
268
267
|
_inputs: MappingProxyType[NodeReference, Any]
|
@@ -101,6 +101,7 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
|
|
101
101
|
request_options = self.request_options or RequestOptions()
|
102
102
|
|
103
103
|
processed_parameters = self.process_parameters(self.parameters)
|
104
|
+
processed_blocks = self.process_blocks(self.blocks)
|
104
105
|
|
105
106
|
request_options["additional_body_parameters"] = {
|
106
107
|
"execution_context": execution_context.model_dump(mode="json"),
|
@@ -139,7 +140,7 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
|
|
139
140
|
input_values=input_values,
|
140
141
|
input_variables=input_variables,
|
141
142
|
parameters=processed_parameters,
|
142
|
-
blocks=
|
143
|
+
blocks=processed_blocks,
|
143
144
|
settings=self.settings,
|
144
145
|
functions=normalized_functions,
|
145
146
|
expand_meta=self.expand_meta,
|
@@ -152,7 +153,7 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
|
|
152
153
|
input_values=input_values,
|
153
154
|
input_variables=input_variables,
|
154
155
|
parameters=processed_parameters,
|
155
|
-
blocks=
|
156
|
+
blocks=processed_blocks,
|
156
157
|
settings=self.settings,
|
157
158
|
functions=normalized_functions,
|
158
159
|
expand_meta=self.expand_meta,
|
@@ -310,3 +311,9 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
|
|
310
311
|
processed_custom_params = normalize_json(parameters.custom_parameters)
|
311
312
|
|
312
313
|
return parameters.model_copy(update={"custom_parameters": processed_custom_params})
|
314
|
+
|
315
|
+
def process_blocks(self, blocks: List[PromptBlock]) -> List[PromptBlock]:
|
316
|
+
"""
|
317
|
+
Override this method to process the blocks before they are executed.
|
318
|
+
"""
|
319
|
+
return blocks
|
@@ -140,6 +140,7 @@ class ToolCallingNode(BaseNode[StateType], Generic[StateType]):
|
|
140
140
|
def _build_graph(self) -> None:
|
141
141
|
# Get the process_parameters method if it exists on this class
|
142
142
|
process_parameters_method = getattr(self.__class__, "process_parameters", None)
|
143
|
+
process_blocks_method = getattr(self.__class__, "process_blocks", None)
|
143
144
|
|
144
145
|
self.tool_prompt_node = create_tool_prompt_node(
|
145
146
|
ml_model=self.ml_model,
|
@@ -149,6 +150,7 @@ class ToolCallingNode(BaseNode[StateType], Generic[StateType]):
|
|
149
150
|
parameters=self.parameters,
|
150
151
|
max_prompt_iterations=self.max_prompt_iterations,
|
151
152
|
process_parameters_method=process_parameters_method,
|
153
|
+
process_blocks_method=process_blocks_method,
|
152
154
|
)
|
153
155
|
|
154
156
|
# Create the router node (handles routing logic only)
|
@@ -14,6 +14,7 @@ from vellum.client.types.prompt_output import PromptOutput
|
|
14
14
|
from vellum.client.types.prompt_parameters import PromptParameters
|
15
15
|
from vellum.client.types.string_chat_message_content import StringChatMessageContent
|
16
16
|
from vellum.client.types.variable_prompt_block import VariablePromptBlock
|
17
|
+
from vellum.workflows.descriptors.base import BaseDescriptor
|
17
18
|
from vellum.workflows.errors.types import WorkflowErrorCode
|
18
19
|
from vellum.workflows.exceptions import NodeException
|
19
20
|
from vellum.workflows.expressions.concat import ConcatExpression
|
@@ -330,6 +331,7 @@ def create_tool_prompt_node(
|
|
330
331
|
parameters: PromptParameters,
|
331
332
|
max_prompt_iterations: Optional[int] = None,
|
332
333
|
process_parameters_method: Optional[Callable] = None,
|
334
|
+
process_blocks_method: Optional[Callable] = None,
|
333
335
|
) -> Type[ToolPromptNode]:
|
334
336
|
if functions and len(functions) > 0:
|
335
337
|
prompt_functions: List[Union[Tool, FunctionDefinition]] = []
|
@@ -400,6 +402,7 @@ def create_tool_prompt_node(
|
|
400
402
|
"parameters": parameters,
|
401
403
|
"max_prompt_iterations": max_prompt_iterations,
|
402
404
|
**({"process_parameters": process_parameters_method} if process_parameters_method is not None else {}),
|
405
|
+
**({"process_blocks": process_blocks_method} if process_blocks_method is not None else {}),
|
403
406
|
"__module__": __name__,
|
404
407
|
},
|
405
408
|
),
|
@@ -529,7 +532,10 @@ def create_function_node(
|
|
529
532
|
inputs = getattr(func, "__vellum_inputs__", {})
|
530
533
|
if inputs:
|
531
534
|
for param_name, param_ref in inputs.items():
|
532
|
-
|
535
|
+
if isinstance(param_ref, BaseDescriptor):
|
536
|
+
resolved_value = param_ref.resolve(self.state)
|
537
|
+
else:
|
538
|
+
resolved_value = param_ref
|
533
539
|
merged_kwargs[param_name] = resolved_value
|
534
540
|
|
535
541
|
return func(**merged_kwargs)
|
vellum/workflows/outputs/base.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
from dataclasses import field
|
2
2
|
import inspect
|
3
|
-
from typing import Any, Generic, Iterator, Set, Tuple, Type, TypeVar, Union, cast
|
3
|
+
from typing import Any, Dict, Generic, Iterator, Set, Tuple, Type, TypeVar, Union, cast
|
4
4
|
from typing_extensions import dataclass_transform
|
5
5
|
|
6
6
|
from pydantic import GetCoreSchemaHandler
|
@@ -10,6 +10,7 @@ from vellum.workflows.constants import undefined
|
|
10
10
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
11
11
|
from vellum.workflows.errors.types import WorkflowErrorCode
|
12
12
|
from vellum.workflows.exceptions import NodeException
|
13
|
+
from vellum.workflows.executable import BaseExecutable
|
13
14
|
from vellum.workflows.references.output import OutputReference
|
14
15
|
from vellum.workflows.types.generics import is_node_instance
|
15
16
|
from vellum.workflows.types.utils import get_class_attr_names, infer_types
|
@@ -99,6 +100,10 @@ class BaseOutput(Generic[_Delta, _Accumulated]):
|
|
99
100
|
|
100
101
|
@dataclass_transform(kw_only_default=True)
|
101
102
|
class _BaseOutputsMeta(type):
|
103
|
+
def __new__(cls, name: str, bases: Tuple[Type, ...], dct: Dict[str, Any]) -> Any:
|
104
|
+
dct["__parent_class__"] = type(None)
|
105
|
+
return super().__new__(cls, name, bases, dct)
|
106
|
+
|
102
107
|
def __eq__(cls, other: Any) -> bool:
|
103
108
|
"""
|
104
109
|
We need to include custom eq logic to prevent infinite loops during ipython reloading.
|
@@ -119,7 +124,13 @@ class _BaseOutputsMeta(type):
|
|
119
124
|
if self_outputs_class.__parent_class__ is None or other_outputs_class.__parent_class__ is None:
|
120
125
|
return super().__eq__(other)
|
121
126
|
|
122
|
-
|
127
|
+
if self_outputs_class.__parent_class__ is type(None) or other_outputs_class.__parent_class__ is type(None):
|
128
|
+
return super().__eq__(other)
|
129
|
+
|
130
|
+
return (
|
131
|
+
self_outputs_class.__parent_class__.__qualname__ == other_outputs_class.__parent_class__.__qualname__
|
132
|
+
and self_outputs_class.__parent_class__.__module__ == other_outputs_class.__parent_class__.__module__
|
133
|
+
)
|
123
134
|
|
124
135
|
def __setattr__(cls, name: str, value: Any) -> None:
|
125
136
|
if isinstance(value, OutputReference):
|
@@ -183,9 +194,7 @@ class _BaseOutputsMeta(type):
|
|
183
194
|
|
184
195
|
|
185
196
|
class BaseOutputs(metaclass=_BaseOutputsMeta):
|
186
|
-
|
187
|
-
# __parent_class__: Type[Union["BaseNode", "BaseWorkflow"]] = field(init=False)
|
188
|
-
__parent_class__: Type = field(init=False)
|
197
|
+
__parent_class__: Type[BaseExecutable] = field(init=False)
|
189
198
|
|
190
199
|
def __init__(self, **kwargs: Any) -> None:
|
191
200
|
declared_fields = {descriptor.name for descriptor in self.__class__}
|
@@ -76,7 +76,7 @@ class OutputReference(BaseDescriptor[_OutputType], Generic[_OutputType]):
|
|
76
76
|
def __eq__(self, other: object) -> bool:
|
77
77
|
if not isinstance(other, type(self)):
|
78
78
|
return False
|
79
|
-
return super().__eq__(other) and
|
79
|
+
return super().__eq__(other) and self._outputs_class == other._outputs_class
|
80
80
|
|
81
81
|
def __hash__(self) -> int:
|
82
82
|
return hash((self._outputs_class, self._name))
|
vellum/workflows/utils/names.py
CHANGED
@@ -2,11 +2,19 @@ import re
|
|
2
2
|
|
3
3
|
|
4
4
|
def pascal_to_title_case(pascal_str: str) -> str:
|
5
|
-
|
6
|
-
title_case_str = re.sub(r"(?<!^)(?=[A-Z])", " ", pascal_str)
|
5
|
+
title_case_str = re.sub(r"(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])", " ", pascal_str)
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
words = title_case_str.split()
|
8
|
+
result_words = []
|
9
|
+
|
10
|
+
for word in words:
|
11
|
+
if word.isupper():
|
12
|
+
result_words.append(word)
|
13
|
+
# Otherwise, apply title case
|
14
|
+
else:
|
15
|
+
result_words.append(word.capitalize())
|
16
|
+
|
17
|
+
return " ".join(result_words)
|
10
18
|
|
11
19
|
|
12
20
|
def snake_to_title_case(snake_str: str) -> str:
|
@@ -8,6 +8,15 @@ from vellum.workflows.utils.names import pascal_to_title_case
|
|
8
8
|
[
|
9
9
|
("MyPascalCaseString", "My Pascal Case String"),
|
10
10
|
("AnotherPascalCaseString", "Another Pascal Case String"),
|
11
|
+
("FetchDeploymentScheme", "Fetch Deployment Scheme"),
|
12
|
+
("CheckDeploymentExists", "Check Deployment Exists"),
|
13
|
+
("APINode", "API Node"),
|
14
|
+
("HTTPSConnection", "HTTPS Connection"),
|
15
|
+
("XMLParser", "XML Parser"),
|
16
|
+
("SimpleWord", "Simple Word"),
|
17
|
+
("A", "A"),
|
18
|
+
("AB", "AB"),
|
19
|
+
("ABCDef", "ABC Def"),
|
11
20
|
],
|
12
21
|
)
|
13
22
|
def test_pascal_to_title_case(input_str, expected):
|
@@ -62,6 +62,7 @@ from vellum.workflows.events.workflow import (
|
|
62
62
|
WorkflowExecutionStreamingBody,
|
63
63
|
WorkflowExecutionStreamingEvent,
|
64
64
|
)
|
65
|
+
from vellum.workflows.executable import BaseExecutable
|
65
66
|
from vellum.workflows.graph import Graph
|
66
67
|
from vellum.workflows.inputs.base import BaseInputs
|
67
68
|
from vellum.workflows.nodes.bases import BaseNode
|
@@ -200,8 +201,7 @@ class _BaseWorkflowMeta(type):
|
|
200
201
|
if inputs_class is not BaseInputs and inputs_class.__parent_class__ is type(None):
|
201
202
|
inputs_class.__parent_class__ = workflow_class
|
202
203
|
|
203
|
-
|
204
|
-
# workflow_class.Outputs.__parent_class__ = workflow_class
|
204
|
+
workflow_class.Outputs.__parent_class__ = workflow_class
|
205
205
|
workflow_class.__output_ids__ = {
|
206
206
|
ref.name: uuid4_from_hash(f"{workflow_class.__id__}|id|{ref.name}") for ref in workflow_class.Outputs
|
207
207
|
}
|
@@ -212,9 +212,7 @@ class _BaseWorkflowMeta(type):
|
|
212
212
|
GraphAttribute = Union[Type[BaseNode], Graph, Set[Type[BaseNode]], Set[Graph]]
|
213
213
|
|
214
214
|
|
215
|
-
class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
|
216
|
-
__id__: UUID = uuid4_from_hash(__qualname__)
|
217
|
-
__output_ids__: Dict[str, UUID] = {}
|
215
|
+
class BaseWorkflow(Generic[InputsType, StateType], BaseExecutable, metaclass=_BaseWorkflowMeta):
|
218
216
|
graph: ClassVar[GraphAttribute]
|
219
217
|
unused_graphs: ClassVar[Set[GraphAttribute]] # nodes or graphs that are defined but not used in the graph
|
220
218
|
emitters: List[BaseWorkflowEmitter]
|
@@ -33,7 +33,7 @@ vellum_ee/workflows/display/nodes/__init__.py,sha256=jI1aPBQf8DkmrYoZ4O-wR1duqZB
|
|
33
33
|
vellum_ee/workflows/display/nodes/base_node_display.py,sha256=98vszulLRvYz0kAh7ZEOeWOqzMtlpnOZM2lAViOUieA,18393
|
34
34
|
vellum_ee/workflows/display/nodes/get_node_display_class.py,sha256=jI_kUi9LnNLDpY63QtlC4TfN8P571VN4LpzH0I1ZtLk,1149
|
35
35
|
vellum_ee/workflows/display/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
|
-
vellum_ee/workflows/display/nodes/tests/test_base_node_display.py,sha256=
|
36
|
+
vellum_ee/workflows/display/nodes/tests/test_base_node_display.py,sha256=Cg5Ker3amAn2wraeNW4t_puvIZdvRB-P8XIL-p4GGL0,3571
|
37
37
|
vellum_ee/workflows/display/nodes/types.py,sha256=St1BB6no528OyELGiyRabWao0GGw6mLhstQAvEACbGk,247
|
38
38
|
vellum_ee/workflows/display/nodes/utils.py,sha256=sloya5TpXsnot1HURc9L51INwflRqUzHxRVnCS9Cd-4,973
|
39
39
|
vellum_ee/workflows/display/nodes/vellum/__init__.py,sha256=nUIgH2s0-7IbQRNrBhLPyRNe8YIrx3Yo9HeeW-aXXFk,1668
|
@@ -81,7 +81,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attr
|
|
81
81
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py,sha256=O1CIKMmRTaMaT3IhjwCAiMz1ZThPg9lAUbSiZkx_E8c,6321
|
82
82
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py,sha256=fPXcX-tWQ0UMuEyOFAylgi7pWiE7lZWk9vrShlTExik,40053
|
83
83
|
vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py,sha256=FLvcD8eoABHUPv08oSpIp_P-65sw2gl4whMXEJJj4f8,6785
|
84
|
-
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py,sha256=
|
84
|
+
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py,sha256=D_ZGMOgr5Ek33ZQagv08b8up1U0Lc0dCgAjnO8ZEpzQ,16336
|
85
85
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py,sha256=arl-tho6f0qstUM2ejONEO4ru_6TxCPbni3FS-UZouQ,30108
|
86
86
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py,sha256=-BiFVw3JUx_79isQNgAtZB2362oByRcuAuUVK9uzCJI,54204
|
87
87
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_default_state_serialization.py,sha256=E1ww97BFoGbnRkxf84TScat5NQhP8nLVrdaOlpGnSKU,8615
|
@@ -100,7 +100,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_nod
|
|
100
100
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_composio_serialization.py,sha256=oVXCjkU0G56QJmqnd_xIwF3D9bhJwALFibM2wmRhwUk,3739
|
101
101
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py,sha256=Sg82qV5NCzQDy-RD90hA6QaHgFHOq6ESNkbWXygsnNw,26367
|
102
102
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_mcp_serialization.py,sha256=QhQbijeCnFeX1i3SMjHJg2WVAEt5JEO3dhFRv-mofdA,2458
|
103
|
-
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_parent_input.py,sha256=
|
103
|
+
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_parent_input.py,sha256=__LX4cuzbyZp_1wc-SI8X_J0tnhOkCEmRVUWLKI5aQM,4578
|
104
104
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py,sha256=cKaxme5vUIvKa8aBU7xdeFxXF9wVZ5fW3T5Ie5vToU0,10152
|
105
105
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_workflow_deployment_serialization.py,sha256=XIZZr5POo2NLn2uEWm9EC3rejeBMoO4X-JtzTH6mvp4,4074
|
106
106
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py,sha256=pLCyMScV88DTBXRH7jXaXOEA1GBq8NIipCUFwIAWnwI,2771
|
@@ -113,7 +113,7 @@ vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
|
|
113
113
|
vellum_ee/workflows/display/utils/auto_layout.py,sha256=f4GiLn_LazweupfqTpubcdtdfE_vrOcmZudSsnYIY9E,3906
|
114
114
|
vellum_ee/workflows/display/utils/events.py,sha256=MEG2BT6GgAzkbv1dMaFpov5OShtaAZeAb1-g3xDFsAM,1826
|
115
115
|
vellum_ee/workflows/display/utils/exceptions.py,sha256=LSwwxCYNxFkf5XMUcFkaZKpQ13OSrI7y_bpEUwbKVk0,169
|
116
|
-
vellum_ee/workflows/display/utils/expressions.py,sha256=
|
116
|
+
vellum_ee/workflows/display/utils/expressions.py,sha256=80TcSWhT249cvT_NRobwelWCLWKgeFQEpXCvjFq0fwY,19743
|
117
117
|
vellum_ee/workflows/display/utils/registry.py,sha256=1qXiBTdsnro6FeCX0FGBEK7CIf6wa--Jt50iZ_nEp_M,3460
|
118
118
|
vellum_ee/workflows/display/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
119
119
|
vellum_ee/workflows/display/utils/tests/test_auto_layout.py,sha256=vfXI769418s9vda5Gb5NFBH747WMOwSgHRXeLCTLVm8,2356
|
@@ -121,7 +121,7 @@ vellum_ee/workflows/display/utils/tests/test_events.py,sha256=Qze6wEmFJx23_sKQhX
|
|
121
121
|
vellum_ee/workflows/display/utils/vellum.py,sha256=sZwU0KdmZZTKWW62SyxJTl2tC8tN6p_BpZ-lDoinV-U,5670
|
122
122
|
vellum_ee/workflows/display/vellum.py,sha256=J2mdJZ1sdLW535DDUkq_Vm8Z572vhuxHxVZF9deKSdk,391
|
123
123
|
vellum_ee/workflows/display/workflows/__init__.py,sha256=JTB9ObEV3l4gGGdtfBHwVJtTTKC22uj-a-XjTVwXCyA,148
|
124
|
-
vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=
|
124
|
+
vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=HEwhGlQ6AllU_SpGSVCYgRc0RXev4iuHxXX3Rl18Xzs,43674
|
125
125
|
vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=gxz76AeCqgAZ9D2lZeTiZzxY9eMgn3qOSfVgiqYcOh8,2028
|
126
126
|
vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=pb7BTH-ivRnya1LQU3j-MApWk_m8POpPNOdD0oEK82A,37847
|
127
127
|
vellum_ee/workflows/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -151,11 +151,11 @@ vellum_ee/workflows/tests/test_serialize_module.py,sha256=lk-4dVnG2HcxxywBXxDR1i
|
|
151
151
|
vellum_ee/workflows/tests/test_server.py,sha256=dXFBraU99Y6cKp2aBhLFXQTScSRcE9WaWjo1z9piqdU,23344
|
152
152
|
vellum_ee/workflows/tests/test_virtual_files.py,sha256=TJEcMR0v2S8CkloXNmCHA0QW0K6pYNGaIjraJz7sFvY,2762
|
153
153
|
vellum/__init__.py,sha256=lv4OTbPgTegugVOpRy5xJPPwMvC1Zqrg4oFMEwY1KSg,47428
|
154
|
-
vellum/client/README.md,sha256=
|
154
|
+
vellum/client/README.md,sha256=flqu57ubZNTfpq60CdLtJC9gp4WEkyjb_n_eZ4OYf9w,6497
|
155
155
|
vellum/client/__init__.py,sha256=T5Ht_w-Mk_9nzGqdadhQB8V20M0vYj7am06ut0A3P1o,73401
|
156
156
|
vellum/client/core/__init__.py,sha256=lTcqUPXcx4112yLDd70RAPeqq6tu3eFMe1pKOqkW9JQ,1562
|
157
157
|
vellum/client/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
|
158
|
-
vellum/client/core/client_wrapper.py,sha256=
|
158
|
+
vellum/client/core/client_wrapper.py,sha256=i5oGjE3DOmkirKwi-u3hUXa3ZSnCYWb06u5EdpjKLMM,2840
|
159
159
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
160
160
|
vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
|
161
161
|
vellum/client/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
|
@@ -950,7 +950,7 @@ vellum/plugins/pydantic.py,sha256=SamPlRZ8V9kuxEfMkOPKjhMMLa5Q3wYJ3Z-F_IfKtvA,39
|
|
950
950
|
vellum/plugins/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
951
951
|
vellum/plugins/tests/test_pydantic.py,sha256=S6bLqs3Y5DGA012QV_7f6hk4e6Bz-iJ9py9DEKuo4fM,746
|
952
952
|
vellum/plugins/utils.py,sha256=cPmxE9R2CK1bki2jKE8rB-G9zMf2pzHjSPDHFPXwd3Q,878
|
953
|
-
vellum/plugins/vellum_mypy.py,sha256=
|
953
|
+
vellum/plugins/vellum_mypy.py,sha256=awSjop_Vn7VRCQZCy5rNUMq8n_ueNjGJ0wHVN-rTVJY,27916
|
954
954
|
vellum/prompts/__init__.py,sha256=kn-btvQOMNnnBuyQiUpie48_VBJAk7tFFU-ul5dwK60,107
|
955
955
|
vellum/prompts/blocks/__init__.py,sha256=Zwvncjd8sUCPmT-8pFpgLYsKJl0xB6td1GTQzjV9hYA,108
|
956
956
|
vellum/prompts/blocks/compilation.py,sha256=mCGfqJXcKMkv565Ye5y9MsPdVAmkCGOnqQBRa3nJVg8,10754
|
@@ -1740,6 +1740,7 @@ vellum/workflows/events/tests/test_event.py,sha256=V26TNmbo2aL4sDvcY3nPxCWgcoS4e
|
|
1740
1740
|
vellum/workflows/events/types.py,sha256=mVrqAH9Hs9SpXm08Hcxdyap_ImQPwGsxRr56rSNMP34,5043
|
1741
1741
|
vellum/workflows/events/workflow.py,sha256=kLSWFXiDZH0TELWoDjQ_kHVomFnw8MVVUPDGIzgyosw,8997
|
1742
1742
|
vellum/workflows/exceptions.py,sha256=NiBiR3ggfmPxBVqD-H1SqmjI-7mIn0EStSN1BqApvCM,1213
|
1743
|
+
vellum/workflows/executable.py,sha256=um-gLJMVYfGJwGJfZIPlCRHhHIYm6pn8PUEfeqrNx5k,218
|
1743
1744
|
vellum/workflows/expressions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1744
1745
|
vellum/workflows/expressions/accessor.py,sha256=3lu1-_-dBfZdJvtX-q66jbmRAZtqIfdsh_3_JNuzg1E,4462
|
1745
1746
|
vellum/workflows/expressions/add.py,sha256=Rr1O83nksL5Z0kam4eaQOokvDrEwlUg7LqWnXzGUW40,1226
|
@@ -1785,9 +1786,9 @@ vellum/workflows/expressions/tests/test_length.py,sha256=pQA1tYSwqxE6euclboY024N
|
|
1785
1786
|
vellum/workflows/expressions/tests/test_minus.py,sha256=pq7dvdRGNhSSn95LGNzRErsYUsFk5SpOKHDcSR5QToc,1632
|
1786
1787
|
vellum/workflows/expressions/tests/test_parse_json.py,sha256=zpB_qE5_EwWQL7ULQUJm0o1PRSfWZdAqZNW6Ah13oJE,1059
|
1787
1788
|
vellum/workflows/graph/__init__.py,sha256=3sHlay5d_-uD7j3QJXiGl0WHFZZ_QScRvgyDhN2GhHY,74
|
1788
|
-
vellum/workflows/graph/graph.py,sha256=
|
1789
|
+
vellum/workflows/graph/graph.py,sha256=vkpteMc2a61IFGHlrA50J4ntVj6m3agcyWrXGQEbjHc,11280
|
1789
1790
|
vellum/workflows/graph/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1790
|
-
vellum/workflows/graph/tests/test_graph.py,sha256=
|
1791
|
+
vellum/workflows/graph/tests/test_graph.py,sha256=0Pov0sCsxjzUDL9wy7xy9jFD-F2GsMJnZVEVFXzQGdM,15433
|
1791
1792
|
vellum/workflows/inputs/__init__.py,sha256=AbFEteIYEvCb14fM3EK7bhM-40-6s494rSlIhQ4Dsss,62
|
1792
1793
|
vellum/workflows/inputs/base.py,sha256=w3owT5B3rLBmIj-v-jL2l-HD4yd3hXK9RmHVd557BpA,5126
|
1793
1794
|
vellum/workflows/inputs/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1799,7 +1800,7 @@ vellum/workflows/integrations/tests/test_mcp_service.py,sha256=q_DYrDkIqI4sQBNgI
|
|
1799
1800
|
vellum/workflows/logging.py,sha256=_a217XogktV4Ncz6xKFz7WfYmZAzkfVRVuC0rWob8ls,437
|
1800
1801
|
vellum/workflows/nodes/__init__.py,sha256=zymtc3_iW2rFmMR-sayTLuN6ZsAw8VnJweWPsjQk2-Q,1197
|
1801
1802
|
vellum/workflows/nodes/bases/__init__.py,sha256=cniHuz_RXdJ4TQgD8CBzoiKDiPxg62ErdVpCbWICX64,58
|
1802
|
-
vellum/workflows/nodes/bases/base.py,sha256=
|
1803
|
+
vellum/workflows/nodes/bases/base.py,sha256=i4tuPo_KyFI1ZJh__AI-oxRkDGch9pNTmOqt69HTcE0,20478
|
1803
1804
|
vellum/workflows/nodes/bases/base_adornment_node.py,sha256=hrgzuTetM4ynPd9YGHoK8Vwwn4XITi3aZZ_OCnQrq4Y,3433
|
1804
1805
|
vellum/workflows/nodes/bases/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1805
1806
|
vellum/workflows/nodes/bases/tests/test_base_adornment_node.py,sha256=fXZI9KqpS4XMBrBnIEkK3foHaBVvyHwYcQWWDKay7ic,1148
|
@@ -1839,7 +1840,7 @@ vellum/workflows/nodes/displayable/bases/api_node/tests/test_node.py,sha256=5C59
|
|
1839
1840
|
vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py,sha256=Org3xTvgp1pA0uUXFfnJr29D3HzCey2lEdYF4zbIUgo,70
|
1840
1841
|
vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=ea20icDM1HB942wkH-XtXNSNCBDcjeOiN3vowkHL4fs,4477
|
1841
1842
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py,sha256=Hl35IAoepRpE-j4cALaXVJIYTYOF3qszyVbxTj4kS1s,82
|
1842
|
-
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=
|
1843
|
+
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=qxABS2tl7gXfU350-0geBMoL25QrgyqR6-vhUAQt4Qk,14065
|
1843
1844
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1844
1845
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py,sha256=Hk_u2IxLIeeqL_s0RTgoyL5QGYwY9VllKT8z5_JHiDU,24956
|
1845
1846
|
vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py,sha256=0a40fkkZkFMmZN0CsWf6EP_y1H6x36EGa3WcfVNyOsM,9797
|
@@ -1893,13 +1894,13 @@ vellum/workflows/nodes/displayable/tests/test_search_node_error_handling.py,sha2
|
|
1893
1894
|
vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py,sha256=VepO5z1277c1y5N6LLIC31nnWD1aak2m5oPFplfJHHs,6935
|
1894
1895
|
vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py,sha256=Bjv-wZyFgNaVZb9KEMMZd9lFoLzbPEPjEMpANizMZw4,2413
|
1895
1896
|
vellum/workflows/nodes/displayable/tool_calling_node/__init__.py,sha256=3n0-ysmFKsr40CVxPthc0rfJgqVJeZuUEsCmYudLVRg,117
|
1896
|
-
vellum/workflows/nodes/displayable/tool_calling_node/node.py,sha256=
|
1897
|
+
vellum/workflows/nodes/displayable/tool_calling_node/node.py,sha256=J4RNOggTx5nzovC0354SPGV-NkRpYnV51PMTYQ7aIQ8,8202
|
1897
1898
|
vellum/workflows/nodes/displayable/tool_calling_node/state.py,sha256=CcBVb_YtwfSSka4ze678k6-qwmzMSfjfVP8_Y95feSo,302
|
1898
1899
|
vellum/workflows/nodes/displayable/tool_calling_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1899
1900
|
vellum/workflows/nodes/displayable/tool_calling_node/tests/test_composio_service.py,sha256=in1fbEz5x1tx3uKv9YXdvOncsHucNL8Ro6Go7lBuuOQ,8962
|
1900
1901
|
vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py,sha256=GZoeybB9uM7ai8sBLAtUMHrMVgh-WrJDWrKZci6feDs,11892
|
1901
1902
|
vellum/workflows/nodes/displayable/tool_calling_node/tests/test_utils.py,sha256=SIu5GCj4tIE4fz-cAcdULtQfqZIhrcc3Doo6TWLXBws,8804
|
1902
|
-
vellum/workflows/nodes/displayable/tool_calling_node/utils.py,sha256=
|
1903
|
+
vellum/workflows/nodes/displayable/tool_calling_node/utils.py,sha256=c0fJA-de3yJKGTzKfjyZOkbVhIndSAhZqBZp_DpU1fg,24158
|
1903
1904
|
vellum/workflows/nodes/displayable/web_search_node/__init__.py,sha256=8FOnEP-n-U68cvxTlJW9wphIAGHq5aqjzLM-DoSSXnU,61
|
1904
1905
|
vellum/workflows/nodes/displayable/web_search_node/node.py,sha256=NQYux2bOtuBF5E4tn-fXi5y3btURPRrNqMSM9MAZYI4,5091
|
1905
1906
|
vellum/workflows/nodes/displayable/web_search_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1914,7 +1915,7 @@ vellum/workflows/nodes/tests/test_mocks.py,sha256=mfPvrs75PKcsNsbJLQAN6PDFoVqs9T
|
|
1914
1915
|
vellum/workflows/nodes/tests/test_utils.py,sha256=BUugAHx2C9YuCwTlsTXV1Glxca0kW3St6T9o_QFatSU,5649
|
1915
1916
|
vellum/workflows/nodes/utils.py,sha256=wCvf8K5qruT5GwtvnHcQ-LMllktTD8aaFmAGpKQy--c,10720
|
1916
1917
|
vellum/workflows/outputs/__init__.py,sha256=AyZ4pRh_ACQIGvkf0byJO46EDnSix1ZCAXfvh-ms1QE,94
|
1917
|
-
vellum/workflows/outputs/base.py,sha256=
|
1918
|
+
vellum/workflows/outputs/base.py,sha256=zy02zr9DmG3j7Xp3Q8xiOiXFF_c7uNh76jf2LiMS-qE,10132
|
1918
1919
|
vellum/workflows/ports/__init__.py,sha256=bZuMt-R7z5bKwpu4uPW7LlJeePOQWmCcDSXe5frUY5g,101
|
1919
1920
|
vellum/workflows/ports/node_ports.py,sha256=SM9uLAaoaE1HwR-Uqwf2v5zZK5iFnphKs6mE5Ls7ldE,2877
|
1920
1921
|
vellum/workflows/ports/port.py,sha256=PYhmzEHgJyjUjSFkPIQ38cNIKpcXrhYiZlj7nZC5yCk,3989
|
@@ -1927,7 +1928,7 @@ vellum/workflows/references/external_input.py,sha256=c_4SojTpykCSbGS1Pjmx9FfquyY
|
|
1927
1928
|
vellum/workflows/references/input.py,sha256=3INu-TLTi4dziWmva6LO3WvgDlPzsjayUx61cVvqLJA,325
|
1928
1929
|
vellum/workflows/references/lazy.py,sha256=jgUYmgt-yAybzPf_R-74MzdU8VuNwMYI8EQqrj9lVR0,2948
|
1929
1930
|
vellum/workflows/references/node.py,sha256=LP854wDVs-9I_aZ7-nkbwXqL2H7W2_3LED2e9FixNS8,1418
|
1930
|
-
vellum/workflows/references/output.py,sha256=
|
1931
|
+
vellum/workflows/references/output.py,sha256=qVa3QmlOyJhyIMOHwOmi1RgHPAOryhdPr2DRj97aEvU,3321
|
1931
1932
|
vellum/workflows/references/state_value.py,sha256=bInUF0A3Pt4-zhA0f6LdSuyv8tz7n5QRkHAEn4gsmqI,711
|
1932
1933
|
vellum/workflows/references/tests/test_lazy.py,sha256=0s50-LizMTlSTBQahpK0fg_xqCucA8YTp6QmIMqPvMk,919
|
1933
1934
|
vellum/workflows/references/vellum_secret.py,sha256=Od4d19a5yletWMqNfJR5d_mZQUkVcFzj29mE-T9J7yE,480
|
@@ -1964,11 +1965,11 @@ vellum/workflows/types/utils.py,sha256=mTctHITBybpt4855x32oCKALBEcMNLn-9cCmfEKgJ
|
|
1964
1965
|
vellum/workflows/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1965
1966
|
vellum/workflows/utils/functions.py,sha256=6WRRMb_XbxtvhUKOJq5ZChy0KKvlBaQCBiPhvecXT7I,10029
|
1966
1967
|
vellum/workflows/utils/hmac.py,sha256=JJCczc6pyV6DuE1Oa0QVfYPUN_of3zEYmGFib3OZnrE,1135
|
1967
|
-
vellum/workflows/utils/names.py,sha256=
|
1968
|
+
vellum/workflows/utils/names.py,sha256=QtHquoaGqRseu5gg2OcVGI2d_CMcEOvjb9KspwH4C-A,552
|
1968
1969
|
vellum/workflows/utils/pydantic_schema.py,sha256=eR_bBtY-T0pttJP-ARwagSdCOnwPUtiT3cegm2lzDTQ,1310
|
1969
1970
|
vellum/workflows/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1970
1971
|
vellum/workflows/utils/tests/test_functions.py,sha256=TlNhD0OBJ-aeYn4qUqmApuajkx9sJx0lIQRMfT8Xf0w,23688
|
1971
|
-
vellum/workflows/utils/tests/test_names.py,sha256=
|
1972
|
+
vellum/workflows/utils/tests/test_names.py,sha256=DnRRnuORxQXx9ESegCzkxiWcHy2_bBi7lXgbFi3FZK8,757
|
1972
1973
|
vellum/workflows/utils/tests/test_uuids.py,sha256=i77ABQ0M3S-aFLzDXHJq_yr5FPkJEWCMBn1HJ3DObrE,437
|
1973
1974
|
vellum/workflows/utils/tests/test_vellum_variables.py,sha256=vbnKgm41aB5OXlO-ZIPbhQ6xDiZkT8KMxCLqz4zocWY,1791
|
1974
1975
|
vellum/workflows/utils/uuids.py,sha256=IaZQANz7fhF7la0_J1O50Y6D2PIYv_taRDTRzBT9aWw,1284
|
@@ -1976,13 +1977,13 @@ vellum/workflows/utils/vellum_variables.py,sha256=YHLNiQGWDNssGH1FQoG9Z1jUFZ-zYe
|
|
1976
1977
|
vellum/workflows/utils/zip.py,sha256=HVg_YZLmBOTXKaDV3Xhaf3V6sYnfqqZXQ8CpuafkbPY,1181
|
1977
1978
|
vellum/workflows/vellum_client.py,sha256=xkfoucodxNK5JR2-lbRqZx3xzDgExWkP6kySrpi_Ubc,1079
|
1978
1979
|
vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
|
1979
|
-
vellum/workflows/workflows/base.py,sha256=
|
1980
|
+
vellum/workflows/workflows/base.py,sha256=4_-kEebUBCn7d4N0TxF-sQejM2gAF8N6FbGabV2t6Pw,28346
|
1980
1981
|
vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
|
1981
1982
|
vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1982
1983
|
vellum/workflows/workflows/tests/test_base_workflow.py,sha256=ptMntHzVyy8ZuzNgeTuk7hREgKQ5UBdgq8VJFSGaW4Y,20832
|
1983
1984
|
vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
|
1984
|
-
vellum_ai-1.3.
|
1985
|
-
vellum_ai-1.3.
|
1986
|
-
vellum_ai-1.3.
|
1987
|
-
vellum_ai-1.3.
|
1988
|
-
vellum_ai-1.3.
|
1985
|
+
vellum_ai-1.3.6.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
1986
|
+
vellum_ai-1.3.6.dist-info/METADATA,sha256=zNFEQuOlfP7i6yEReP2nVPoXRzJ6wvJWmK_OAs8oz1Q,5547
|
1987
|
+
vellum_ai-1.3.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
1988
|
+
vellum_ai-1.3.6.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
|
1989
|
+
vellum_ai-1.3.6.dist-info/RECORD,,
|
@@ -100,3 +100,20 @@ def test_serialize_display_data():
|
|
100
100
|
"position": {"x": 0.0, "y": 0.0},
|
101
101
|
"comment": {"expanded": True, "value": "I hope this works"},
|
102
102
|
}
|
103
|
+
|
104
|
+
|
105
|
+
def test_serialize_node_label_with_pascal_case():
|
106
|
+
"""
|
107
|
+
Tests that a node with PascalCase name serializes with proper title case label.
|
108
|
+
"""
|
109
|
+
|
110
|
+
# GIVEN a node with a PascalCase name that includes common patterns
|
111
|
+
class MyCustomNode(BaseNode):
|
112
|
+
pass
|
113
|
+
|
114
|
+
# WHEN we serialize the node
|
115
|
+
node_display_class = get_node_display_class(MyCustomNode)
|
116
|
+
data = node_display_class().serialize(WorkflowDisplayContext())
|
117
|
+
|
118
|
+
# THEN the label should be converted to proper title case with spaces
|
119
|
+
assert data["label"] == "My Custom Node"
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py
CHANGED
@@ -173,7 +173,7 @@ def test_serialize_workflow(vellum_client):
|
|
173
173
|
},
|
174
174
|
],
|
175
175
|
"data": {
|
176
|
-
"label": "Simple
|
176
|
+
"label": "Simple API Node",
|
177
177
|
"error_output_id": None,
|
178
178
|
"source_handle_id": "7c33b4d3-9204-4bd5-9371-80ee34f83073",
|
179
179
|
"target_handle_id": "14b538a5-aedb-41f3-b579-039956b7c7ed",
|
@@ -73,11 +73,15 @@ def test_serialize_workflow():
|
|
73
73
|
"node_id": "8e89ae10-a709-45ec-89f8-242f92e4a83f",
|
74
74
|
"node_output_id": "0cd09f0a-c142-4d5d-acc7-b93cd30ca58d",
|
75
75
|
},
|
76
|
+
"constant_input": {
|
77
|
+
"type": "CONSTANT_VALUE",
|
78
|
+
"value": {"type": "STRING", "value": "constant_input"},
|
79
|
+
},
|
76
80
|
},
|
77
81
|
"forced": None,
|
78
82
|
"strict": None,
|
79
83
|
},
|
80
|
-
"src": 'from vellum.workflows.utils.functions import use_tool_inputs\n\nfrom .inputs import ParentInputs\nfrom .nodes.dummy_node import DummyNode\n\n\n@use_tool_inputs(\n parent_input=ParentInputs.parent_input,\n dummy_input=DummyNode.Outputs.text,\n)\ndef get_string(parent_input: str, dummy_input: str, populated_input: str) -> str:\n """\n Get a string with the parent input, dummy input, and the populated input.\n """\n return f"
|
84
|
+
"src": 'from vellum.workflows.utils.functions import use_tool_inputs\n\nfrom .inputs import ParentInputs\nfrom .nodes.dummy_node import DummyNode\n\n\n@use_tool_inputs(\n parent_input=ParentInputs.parent_input,\n dummy_input=DummyNode.Outputs.text,\n constant_input="constant_input",\n)\ndef get_string(parent_input: str, dummy_input: str, constant_input: str, populated_input: str) -> str:\n """\n Get a string with the parent input, dummy input, and the populated input.\n """\n return f"parent input: {parent_input}, dummy input: {dummy_input}, constant input: {constant_input}, populated input: {populated_input}" # noqa: E501\n', # noqa: E501
|
81
85
|
}
|
82
86
|
],
|
83
87
|
},
|
@@ -6,8 +6,8 @@ from typing import TYPE_CHECKING, Any, Dict, List, cast
|
|
6
6
|
|
7
7
|
from pydantic import BaseModel
|
8
8
|
|
9
|
-
from vellum.client.types.function_definition import FunctionDefinition
|
10
9
|
from vellum.client.types.logical_operator import LogicalOperator
|
10
|
+
from vellum.workflows.constants import undefined
|
11
11
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
12
12
|
from vellum.workflows.expressions.accessor import AccessorExpression
|
13
13
|
from vellum.workflows.expressions.add import AddExpression
|
@@ -244,7 +244,14 @@ def serialize_key(key: Any) -> str:
|
|
244
244
|
return str(key)
|
245
245
|
|
246
246
|
|
247
|
+
# Sentinel value to indicate a value should be omitted from serialization
|
248
|
+
_UNDEFINED_SENTINEL: JsonObject = {"__undefined__": True}
|
249
|
+
|
250
|
+
|
247
251
|
def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> JsonObject:
|
252
|
+
if value is undefined:
|
253
|
+
return _UNDEFINED_SENTINEL
|
254
|
+
|
248
255
|
if isinstance(value, ConstantValueReference):
|
249
256
|
return serialize_value(display_context, value._value)
|
250
257
|
|
@@ -315,7 +322,12 @@ def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> Js
|
|
315
322
|
}
|
316
323
|
|
317
324
|
if isinstance(value, list):
|
318
|
-
serialized_items = [
|
325
|
+
serialized_items = []
|
326
|
+
for item in value:
|
327
|
+
serialized_item = serialize_value(display_context, item)
|
328
|
+
if serialized_item != _UNDEFINED_SENTINEL:
|
329
|
+
serialized_items.append(serialized_item)
|
330
|
+
|
319
331
|
if all(isinstance(item, dict) and item["type"] == "CONSTANT_VALUE" for item in serialized_items):
|
320
332
|
constant_values = []
|
321
333
|
for item in serialized_items:
|
@@ -346,14 +358,17 @@ def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> Js
|
|
346
358
|
return serialize_value(display_context, dict_value)
|
347
359
|
|
348
360
|
if isinstance(value, dict):
|
349
|
-
serialized_entries: List[Dict[str, Any]] = [
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
361
|
+
serialized_entries: List[Dict[str, Any]] = []
|
362
|
+
for key, val in value.items():
|
363
|
+
serialized_val = serialize_value(display_context, val)
|
364
|
+
if serialized_val != _UNDEFINED_SENTINEL:
|
365
|
+
serialized_entries.append(
|
366
|
+
{
|
367
|
+
"id": str(uuid4_from_hash(f"{key}|{val}")),
|
368
|
+
"key": serialize_key(key),
|
369
|
+
"value": serialized_val,
|
370
|
+
}
|
371
|
+
)
|
357
372
|
|
358
373
|
# Check if all entries have constant values
|
359
374
|
if all(entry["value"]["type"] == "CONSTANT_VALUE" for entry in serialized_entries):
|
@@ -423,6 +438,10 @@ def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> Js
|
|
423
438
|
|
424
439
|
if callable(value):
|
425
440
|
function_definition = compile_function_definition(value)
|
441
|
+
|
442
|
+
name = function_definition.name
|
443
|
+
description = function_definition.description or ""
|
444
|
+
|
426
445
|
inputs = getattr(value, "__vellum_inputs__", {})
|
427
446
|
|
428
447
|
if inputs:
|
@@ -432,7 +451,9 @@ def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> Js
|
|
432
451
|
|
433
452
|
model_data = function_definition.model_dump()
|
434
453
|
model_data["inputs"] = serialized_inputs
|
435
|
-
|
454
|
+
function_definition_data = model_data
|
455
|
+
else:
|
456
|
+
function_definition_data = function_definition.model_dump()
|
436
457
|
|
437
458
|
source_path = inspect.getsourcefile(value)
|
438
459
|
if source_path is not None:
|
@@ -447,9 +468,9 @@ def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> Js
|
|
447
468
|
"type": "JSON",
|
448
469
|
"value": {
|
449
470
|
"type": "CODE_EXECUTION",
|
450
|
-
"name":
|
451
|
-
"description":
|
452
|
-
"definition":
|
471
|
+
"name": name,
|
472
|
+
"description": description,
|
473
|
+
"definition": function_definition_data,
|
453
474
|
"src": source_code,
|
454
475
|
},
|
455
476
|
},
|
@@ -599,7 +599,7 @@ class BaseWorkflowDisplay(Generic[WorkflowType]):
|
|
599
599
|
|
600
600
|
workflow_output_display = self.output_displays.get(workflow_output)
|
601
601
|
workflow_output_displays[workflow_output] = (
|
602
|
-
workflow_output_display or self._generate_workflow_output_display(workflow_output
|
602
|
+
workflow_output_display or self._generate_workflow_output_display(workflow_output)
|
603
603
|
)
|
604
604
|
|
605
605
|
return WorkflowDisplayContext(
|
@@ -688,14 +688,8 @@ class BaseWorkflowDisplay(Generic[WorkflowType]):
|
|
688
688
|
|
689
689
|
return EntrypointDisplay(id=entrypoint_id, edge_display=edge_display)
|
690
690
|
|
691
|
-
def _generate_workflow_output_display(
|
692
|
-
|
693
|
-
) -> WorkflowOutputDisplay:
|
694
|
-
# TODO: use the output.id field instead once we add `__parent_class__` to BaseWorkflow.Outputs
|
695
|
-
output_id = workflow_class.__output_ids__.get(output.name) or uuid4_from_hash(
|
696
|
-
f"{self.workflow_id}|id|{output.name}"
|
697
|
-
)
|
698
|
-
return WorkflowOutputDisplay(id=output_id, name=output.name)
|
691
|
+
def _generate_workflow_output_display(self, output: OutputReference) -> WorkflowOutputDisplay:
|
692
|
+
return WorkflowOutputDisplay(id=output.id, name=output.name)
|
699
693
|
|
700
694
|
def __init_subclass__(cls, **kwargs: Any) -> None:
|
701
695
|
super().__init_subclass__(**kwargs)
|
File without changes
|
File without changes
|
File without changes
|