vellum-ai 0.14.1__py3-none-any.whl → 0.14.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vellum/client/core/client_wrapper.py +1 -1
- vellum/utils/templating/constants.py +6 -2
- vellum/utils/templating/custom_filters.py +22 -1
- vellum/utils/templating/render.py +3 -2
- vellum/utils/templating/tests/__init__.py +0 -0
- vellum/utils/templating/tests/test_custom_filters.py +19 -0
- vellum/workflows/errors/types.py +3 -0
- vellum/workflows/nodes/core/templating_node/node.py +3 -3
- vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py +27 -0
- vellum/workflows/nodes/displayable/code_execution_node/node.py +5 -4
- vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +51 -0
- vellum/workflows/nodes/displayable/code_execution_node/utils.py +13 -11
- {vellum_ai-0.14.1.dist-info → vellum_ai-0.14.2.dist-info}/METADATA +1 -1
- {vellum_ai-0.14.1.dist-info → vellum_ai-0.14.2.dist-info}/RECORD +21 -19
- vellum_cli/pull.py +3 -11
- vellum_ee/workflows/display/vellum.py +1 -1
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py +13 -6
- vellum_ee/workflows/tests/local_workflow/display/workflow.py +0 -2
- {vellum_ai-0.14.1.dist-info → vellum_ai-0.14.2.dist-info}/LICENSE +0 -0
- {vellum_ai-0.14.1.dist-info → vellum_ai-0.14.2.dist-info}/WHEEL +0 -0
- {vellum_ai-0.14.1.dist-info → vellum_ai-0.14.2.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.14.
|
21
|
+
"X-Fern-SDK-Version": "0.14.2",
|
22
22
|
}
|
23
23
|
headers["X_API_KEY"] = self.api_key
|
24
24
|
return headers
|
@@ -10,7 +10,7 @@ import pydash
|
|
10
10
|
import pytz
|
11
11
|
import yaml
|
12
12
|
|
13
|
-
from vellum.utils.templating.custom_filters import is_valid_json_string
|
13
|
+
from vellum.utils.templating.custom_filters import is_valid_json_string, replace
|
14
14
|
|
15
15
|
DEFAULT_JINJA_GLOBALS: Dict[str, Any] = {
|
16
16
|
"datetime": datetime,
|
@@ -23,6 +23,10 @@ DEFAULT_JINJA_GLOBALS: Dict[str, Any] = {
|
|
23
23
|
"re": re,
|
24
24
|
"yaml": yaml,
|
25
25
|
}
|
26
|
-
|
26
|
+
|
27
|
+
FilterFunc = Union[Callable[[Union[str, bytes]], bool], Callable[[Any, Any, Any], str]]
|
28
|
+
|
29
|
+
DEFAULT_JINJA_CUSTOM_FILTERS: Dict[str, FilterFunc] = {
|
27
30
|
"is_valid_json_string": is_valid_json_string,
|
31
|
+
"replace": replace,
|
28
32
|
}
|
@@ -1,5 +1,7 @@
|
|
1
1
|
import json
|
2
|
-
from typing import Union
|
2
|
+
from typing import Any, Union
|
3
|
+
|
4
|
+
from vellum.workflows.state.encoder import DefaultStateEncoder
|
3
5
|
|
4
6
|
|
5
7
|
def is_valid_json_string(value: Union[str, bytes]) -> bool:
|
@@ -10,3 +12,22 @@ def is_valid_json_string(value: Union[str, bytes]) -> bool:
|
|
10
12
|
except ValueError:
|
11
13
|
return False
|
12
14
|
return True
|
15
|
+
|
16
|
+
|
17
|
+
def replace(s: Any, old: Any, new: Any) -> str:
|
18
|
+
def encode_to_str(obj: Any) -> str:
|
19
|
+
"""Encode an object for template rendering using DefaultStateEncoder."""
|
20
|
+
try:
|
21
|
+
if isinstance(obj, str):
|
22
|
+
return obj
|
23
|
+
return json.dumps(obj, cls=DefaultStateEncoder)
|
24
|
+
except TypeError:
|
25
|
+
return str(obj)
|
26
|
+
|
27
|
+
if old == "":
|
28
|
+
return encode_to_str(s)
|
29
|
+
|
30
|
+
s_str = encode_to_str(s)
|
31
|
+
old_str = encode_to_str(old)
|
32
|
+
new_str = encode_to_str(new)
|
33
|
+
return s_str.replace(old_str, new_str)
|
@@ -1,8 +1,9 @@
|
|
1
1
|
import json
|
2
|
-
from typing import Any,
|
2
|
+
from typing import Any, Dict, Optional
|
3
3
|
|
4
4
|
from jinja2.sandbox import SandboxedEnvironment
|
5
5
|
|
6
|
+
from vellum.utils.templating.constants import FilterFunc
|
6
7
|
from vellum.utils.templating.exceptions import JinjaTemplateError
|
7
8
|
from vellum.workflows.state.encoder import DefaultStateEncoder
|
8
9
|
|
@@ -18,7 +19,7 @@ def render_sandboxed_jinja_template(
|
|
18
19
|
*,
|
19
20
|
template: str,
|
20
21
|
input_values: Dict[str, Any],
|
21
|
-
jinja_custom_filters: Optional[Dict[str,
|
22
|
+
jinja_custom_filters: Optional[Dict[str, FilterFunc]] = None,
|
22
23
|
jinja_globals: Optional[Dict[str, Any]] = None,
|
23
24
|
) -> str:
|
24
25
|
"""Render a Jinja template within a sandboxed environment."""
|
File without changes
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from vellum.utils.templating.custom_filters import replace
|
4
|
+
|
5
|
+
|
6
|
+
@pytest.mark.parametrize(
|
7
|
+
["input_str", "old", "new", "expected"],
|
8
|
+
[
|
9
|
+
("foo", "foo", "bar", "bar"),
|
10
|
+
({"message": "hello"}, "hello", "world", '{"message": "world"}'),
|
11
|
+
("Value: 123", 123, 456, "Value: 456"),
|
12
|
+
(123, 2, 4, "143"),
|
13
|
+
("", "", "", ""),
|
14
|
+
("foo", "", "bar", "foo"),
|
15
|
+
],
|
16
|
+
)
|
17
|
+
def test_replace(input_str, old, new, expected):
|
18
|
+
actual = replace(input_str, old, new)
|
19
|
+
assert actual == expected
|
vellum/workflows/errors/types.py
CHANGED
@@ -13,6 +13,7 @@ class WorkflowErrorCode(Enum):
|
|
13
13
|
INVALID_INPUTS = "INVALID_INPUTS"
|
14
14
|
INVALID_OUTPUTS = "INVALID_OUTPUTS"
|
15
15
|
INVALID_STATE = "INVALID_STATE"
|
16
|
+
INVALID_CODE = "INVALID_CODE"
|
16
17
|
INVALID_TEMPLATE = "INVALID_TEMPLATE"
|
17
18
|
INTERNAL_ERROR = "INTERNAL_ERROR"
|
18
19
|
NODE_EXECUTION = "NODE_EXECUTION"
|
@@ -54,6 +55,7 @@ _WORKFLOW_EVENT_ERROR_CODE_TO_WORKFLOW_ERROR_CODE: Dict[WorkflowExecutionEventEr
|
|
54
55
|
"INTERNAL_SERVER_ERROR": WorkflowErrorCode.INTERNAL_ERROR,
|
55
56
|
"NODE_EXECUTION": WorkflowErrorCode.NODE_EXECUTION,
|
56
57
|
"LLM_PROVIDER": WorkflowErrorCode.PROVIDER_ERROR,
|
58
|
+
"INVALID_CODE": WorkflowErrorCode.INVALID_CODE,
|
57
59
|
"INVALID_TEMPLATE": WorkflowErrorCode.INVALID_TEMPLATE,
|
58
60
|
"USER_DEFINED_ERROR": WorkflowErrorCode.USER_DEFINED_ERROR,
|
59
61
|
}
|
@@ -71,6 +73,7 @@ _WORKFLOW_ERROR_CODE_TO_VELLUM_ERROR_CODE: Dict[WorkflowErrorCode, VellumErrorCo
|
|
71
73
|
WorkflowErrorCode.INVALID_INPUTS: "INVALID_INPUTS",
|
72
74
|
WorkflowErrorCode.INVALID_OUTPUTS: "INVALID_REQUEST",
|
73
75
|
WorkflowErrorCode.INVALID_STATE: "INVALID_REQUEST",
|
76
|
+
WorkflowErrorCode.INVALID_CODE: "INVALID_CODE",
|
74
77
|
WorkflowErrorCode.INVALID_TEMPLATE: "INVALID_INPUTS",
|
75
78
|
WorkflowErrorCode.INTERNAL_ERROR: "INTERNAL_SERVER_ERROR",
|
76
79
|
WorkflowErrorCode.NODE_EXECUTION: "USER_DEFINED_ERROR",
|
@@ -1,6 +1,6 @@
|
|
1
|
-
from typing import Any,
|
1
|
+
from typing import Any, ClassVar, Dict, Generic, Mapping, Tuple, Type, TypeVar, get_args
|
2
2
|
|
3
|
-
from vellum.utils.templating.constants import DEFAULT_JINJA_CUSTOM_FILTERS, DEFAULT_JINJA_GLOBALS
|
3
|
+
from vellum.utils.templating.constants import DEFAULT_JINJA_CUSTOM_FILTERS, DEFAULT_JINJA_GLOBALS, FilterFunc
|
4
4
|
from vellum.utils.templating.exceptions import JinjaTemplateError
|
5
5
|
from vellum.utils.templating.render import render_sandboxed_jinja_template
|
6
6
|
from vellum.workflows.errors import WorkflowErrorCode
|
@@ -54,7 +54,7 @@ class TemplatingNode(BaseNode[StateType], Generic[StateType, _OutputType], metac
|
|
54
54
|
inputs: ClassVar[EntityInputsInterface]
|
55
55
|
|
56
56
|
jinja_globals: Dict[str, Any] = DEFAULT_JINJA_GLOBALS
|
57
|
-
jinja_custom_filters: Mapping[str,
|
57
|
+
jinja_custom_filters: Mapping[str, FilterFunc] = DEFAULT_JINJA_CUSTOM_FILTERS
|
58
58
|
|
59
59
|
class Outputs(BaseNode.Outputs):
|
60
60
|
"""
|
@@ -4,6 +4,7 @@ from typing import List, Union
|
|
4
4
|
|
5
5
|
from vellum.client.types.chat_message import ChatMessage
|
6
6
|
from vellum.client.types.function_call import FunctionCall
|
7
|
+
from vellum.client.types.function_call_vellum_value import FunctionCallVellumValue
|
7
8
|
from vellum.workflows.exceptions import NodeException
|
8
9
|
from vellum.workflows.nodes.bases.base import BaseNode
|
9
10
|
from vellum.workflows.nodes.core.templating_node.node import TemplatingNode
|
@@ -193,3 +194,29 @@ def test_templating_node__union_float_int_output():
|
|
193
194
|
|
194
195
|
# THEN it should correctly parse as a float
|
195
196
|
assert outputs.result == 42.5
|
197
|
+
|
198
|
+
|
199
|
+
def test_templating_node__replace_filter():
|
200
|
+
# GIVEN a templating node that outputs a complex object
|
201
|
+
class ReplaceFilterTemplateNode(TemplatingNode[BaseState, Json]):
|
202
|
+
template = """{{- prompt_outputs | selectattr(\'type\', \'equalto\', \'FUNCTION_CALL\') \
|
203
|
+
| list | replace(\"\\n\",\",\") -}}"""
|
204
|
+
inputs = {
|
205
|
+
"prompt_outputs": [FunctionCallVellumValue(value=FunctionCall(name="test", arguments={"key": "value"}))]
|
206
|
+
}
|
207
|
+
|
208
|
+
# WHEN the node is run
|
209
|
+
node = ReplaceFilterTemplateNode()
|
210
|
+
outputs = node.run()
|
211
|
+
|
212
|
+
# THEN the output is the expected JSON
|
213
|
+
assert outputs.result == [
|
214
|
+
{
|
215
|
+
"type": "FUNCTION_CALL",
|
216
|
+
"value": {
|
217
|
+
"name": "test",
|
218
|
+
"arguments": {"key": "value"},
|
219
|
+
"id": None,
|
220
|
+
},
|
221
|
+
}
|
222
|
+
]
|
@@ -93,13 +93,14 @@ class CodeExecutionNode(BaseNode[StateType], Generic[StateType, _OutputType], me
|
|
93
93
|
log: str
|
94
94
|
|
95
95
|
def run(self) -> Outputs:
|
96
|
-
input_values = self._compile_code_inputs()
|
97
96
|
output_type = self.__class__.get_output_type()
|
98
97
|
code = self._resolve_code()
|
99
98
|
if not self.packages and self.runtime == "PYTHON_3_11_6":
|
100
|
-
logs, result = run_code_inline(code,
|
99
|
+
logs, result = run_code_inline(code, self.code_inputs, output_type)
|
101
100
|
return self.Outputs(result=result, log=logs)
|
101
|
+
|
102
102
|
else:
|
103
|
+
input_values = self._compile_code_inputs()
|
103
104
|
expected_output_type = primitive_type_to_vellum_variable_type(output_type)
|
104
105
|
|
105
106
|
code_execution_result = self._context.vellum_client.execute_code(
|
@@ -131,7 +132,7 @@ class CodeExecutionNode(BaseNode[StateType], Generic[StateType, _OutputType], me
|
|
131
132
|
compiled_inputs.append(
|
132
133
|
StringInput(
|
133
134
|
name=input_name,
|
134
|
-
value=
|
135
|
+
value=input_value,
|
135
136
|
)
|
136
137
|
)
|
137
138
|
elif isinstance(input_value, VellumSecret):
|
@@ -193,7 +194,7 @@ class CodeExecutionNode(BaseNode[StateType], Generic[StateType, _OutputType], me
|
|
193
194
|
)
|
194
195
|
else:
|
195
196
|
raise NodeException(
|
196
|
-
message=f"Unrecognized input type for input '{input_name}'",
|
197
|
+
message=f"Unrecognized input type for input '{input_name}': {input_value.__class__.__name__}",
|
197
198
|
code=WorkflowErrorCode.INVALID_INPUTS,
|
198
199
|
)
|
199
200
|
|
@@ -7,6 +7,7 @@ from vellum.client.types.code_execution_package import CodeExecutionPackage
|
|
7
7
|
from vellum.client.types.code_executor_secret_input import CodeExecutorSecretInput
|
8
8
|
from vellum.client.types.function_call import FunctionCall
|
9
9
|
from vellum.client.types.number_input import NumberInput
|
10
|
+
from vellum.workflows.errors import WorkflowErrorCode
|
10
11
|
from vellum.workflows.exceptions import NodeException
|
11
12
|
from vellum.workflows.inputs.base import BaseInputs
|
12
13
|
from vellum.workflows.nodes.displayable.code_execution_node import CodeExecutionNode
|
@@ -559,3 +560,53 @@ def main(arg1: List[Dict]) -> float:
|
|
559
560
|
|
560
561
|
# AND we should not have invoked the Code via Vellum since it's running inline
|
561
562
|
vellum_client.execute_code.assert_not_called()
|
563
|
+
|
564
|
+
|
565
|
+
def test_run_node__code_execution_error():
|
566
|
+
# GIVEN a node that will raise an error during execution
|
567
|
+
class State(BaseState):
|
568
|
+
pass
|
569
|
+
|
570
|
+
class ExampleCodeExecutionNode(CodeExecutionNode[State, int]):
|
571
|
+
code = """\
|
572
|
+
def main(arg1: int, arg2: int) -> int:
|
573
|
+
return arg1 + arg2 + arg3
|
574
|
+
"""
|
575
|
+
runtime = "PYTHON_3_11_6"
|
576
|
+
code_inputs = {
|
577
|
+
"arg1": 1,
|
578
|
+
"arg2": 2,
|
579
|
+
}
|
580
|
+
|
581
|
+
# WHEN we run the node
|
582
|
+
node = ExampleCodeExecutionNode(state=State())
|
583
|
+
|
584
|
+
# THEN it should raise a NodeException with the execution error
|
585
|
+
with pytest.raises(NodeException) as exc_info:
|
586
|
+
node.run()
|
587
|
+
|
588
|
+
# AND the error should contain the execution error details
|
589
|
+
assert "name 'arg3' is not defined" in str(exc_info.value)
|
590
|
+
assert exc_info.value.code == WorkflowErrorCode.INVALID_CODE
|
591
|
+
|
592
|
+
|
593
|
+
def test_run_node__array_of_bools_input():
|
594
|
+
# GIVEN a node that will raise an error during execution
|
595
|
+
class ExampleCodeExecutionNode(CodeExecutionNode[BaseState, int]):
|
596
|
+
code = """\
|
597
|
+
def main(arg1: list[bool]) -> int:
|
598
|
+
return len(arg1)
|
599
|
+
"""
|
600
|
+
runtime = "PYTHON_3_11_6"
|
601
|
+
code_inputs = {
|
602
|
+
"arg1": [True, False, True],
|
603
|
+
}
|
604
|
+
|
605
|
+
# WHEN we run the node
|
606
|
+
node = ExampleCodeExecutionNode()
|
607
|
+
|
608
|
+
# THEN it should raise a NodeException with the execution error
|
609
|
+
outputs = node.run()
|
610
|
+
|
611
|
+
# AND the error should contain the execution error details
|
612
|
+
assert outputs == {"result": 3, "log": ""}
|
@@ -1,14 +1,13 @@
|
|
1
1
|
import io
|
2
2
|
import os
|
3
3
|
import re
|
4
|
-
from typing import Any,
|
4
|
+
from typing import Any, Tuple, Union, get_args, get_origin
|
5
5
|
|
6
6
|
from pydantic import BaseModel, ValidationError
|
7
7
|
|
8
|
-
from vellum import VellumValue
|
9
|
-
from vellum.client.types.code_executor_input import CodeExecutorInput
|
10
8
|
from vellum.workflows.errors.types import WorkflowErrorCode
|
11
9
|
from vellum.workflows.exceptions import NodeException
|
10
|
+
from vellum.workflows.types.core import EntityInputsInterface
|
12
11
|
|
13
12
|
|
14
13
|
def read_file_from_path(node_filepath: str, script_filepath: str) -> Union[str, None]:
|
@@ -70,13 +69,11 @@ def _clean_for_dict_wrapper(obj):
|
|
70
69
|
|
71
70
|
def run_code_inline(
|
72
71
|
code: str,
|
73
|
-
|
72
|
+
inputs: EntityInputsInterface,
|
74
73
|
output_type: Any,
|
75
74
|
) -> Tuple[str, Any]:
|
76
75
|
log_buffer = io.StringIO()
|
77
76
|
|
78
|
-
VELLUM_TYPES = get_args(VellumValue)
|
79
|
-
|
80
77
|
def wrap_value(value):
|
81
78
|
if isinstance(value, list):
|
82
79
|
return ListWrapper(
|
@@ -84,7 +81,7 @@ def run_code_inline(
|
|
84
81
|
# Convert VellumValue to dict with its fields
|
85
82
|
(
|
86
83
|
item.model_dump()
|
87
|
-
if isinstance(item,
|
84
|
+
if isinstance(item, BaseModel)
|
88
85
|
else _clean_for_dict_wrapper(item) if isinstance(item, (dict, list)) else item
|
89
86
|
)
|
90
87
|
for item in value
|
@@ -93,18 +90,23 @@ def run_code_inline(
|
|
93
90
|
return _clean_for_dict_wrapper(value)
|
94
91
|
|
95
92
|
exec_globals = {
|
96
|
-
"__arg__inputs": {
|
93
|
+
"__arg__inputs": {name: wrap_value(value) for name, value in inputs.items()},
|
97
94
|
"__arg__out": None,
|
98
95
|
"print": lambda *args, **kwargs: log_buffer.write(f"{' '.join(args)}\n"),
|
99
96
|
}
|
100
|
-
run_args = [f"{
|
97
|
+
run_args = [f"{name}=__arg__inputs['{name}']" for name in inputs.keys()]
|
101
98
|
execution_code = f"""\
|
102
99
|
{code}
|
103
100
|
|
104
101
|
__arg__out = main({", ".join(run_args)})
|
105
102
|
"""
|
106
|
-
|
107
|
-
|
103
|
+
try:
|
104
|
+
exec(execution_code, exec_globals)
|
105
|
+
except Exception as e:
|
106
|
+
raise NodeException(
|
107
|
+
code=WorkflowErrorCode.INVALID_CODE,
|
108
|
+
message=str(e),
|
109
|
+
)
|
108
110
|
|
109
111
|
logs = log_buffer.getvalue()
|
110
112
|
result = exec_globals["__arg__out"]
|
@@ -6,7 +6,7 @@ vellum_cli/config.py,sha256=Bsb3mnvKvv3oOTcCuxpgC7lWPMqt6eJhgRA6VEE-vL4,9266
|
|
6
6
|
vellum_cli/image_push.py,sha256=SJwhwWJsLjwGNezNVd_oCVpFMfPsAB3dfLWmriZZUtw,4419
|
7
7
|
vellum_cli/logger.py,sha256=PuRFa0WCh4sAGFS5aqWB0QIYpS6nBWwPJrIXpWxugV4,1022
|
8
8
|
vellum_cli/ping.py,sha256=lWyJw6sziXjyTopTYRdFF5hV-sYPVDdX0yVbG5fzcY4,585
|
9
|
-
vellum_cli/pull.py,sha256=
|
9
|
+
vellum_cli/pull.py,sha256=SA2EOHXbLO_jGKhzUHNrLyxEwaPbeLiU3TeRY5oeX_Y,8877
|
10
10
|
vellum_cli/push.py,sha256=xjTNbLwOVFNU3kpBrm56Bk5QkSRrJ9z86qceghCzfIA,9655
|
11
11
|
vellum_cli/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
12
|
vellum_cli/tests/conftest.py,sha256=AFYZryKA2qnUuCPBxBKmHLFoPiE0WhBFFej9tNwSHdc,1526
|
@@ -84,12 +84,12 @@ vellum_ee/workflows/display/types.py,sha256=bm355ZcZ-7WaesBvIB8RbWDD7qiFmazfcNb6
|
|
84
84
|
vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
85
85
|
vellum_ee/workflows/display/utils/expressions.py,sha256=9FpOslDI-RCR5m4TgAu9KCHh4aTVnh7CHR2ykyMUDw0,1151
|
86
86
|
vellum_ee/workflows/display/utils/vellum.py,sha256=UjK_RxnSEmlIu9klGCPWU5RAQBmgZ7cRbRdgxaTbubE,8081
|
87
|
-
vellum_ee/workflows/display/vellum.py,sha256=
|
87
|
+
vellum_ee/workflows/display/vellum.py,sha256=iiBzMIHTnRb-Xb4Q9-26vOxPpK_rDPKBlky3dBew8Gg,8480
|
88
88
|
vellum_ee/workflows/display/workflows/__init__.py,sha256=kapXsC67VJcgSuiBMa86FdePG5A9kMB5Pi4Uy1O2ob4,207
|
89
89
|
vellum_ee/workflows/display/workflows/base_workflow_display.py,sha256=Amow11LhE-GL3j8bNZ8rK1iYKjkNOhH1ECMQ-dvyLAU,17204
|
90
90
|
vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha256=kp0u8LN_2IwshLrhMImhpZx1hRyAcD5gXY-kDuuaGMQ,1269
|
91
91
|
vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=yl1ytpl9_lijOGeDPWSypWYRJ7aOEVA7NgUg81jTuCs,2229
|
92
|
-
vellum_ee/workflows/display/workflows/vellum_workflow_display.py,sha256=
|
92
|
+
vellum_ee/workflows/display/workflows/vellum_workflow_display.py,sha256=8roVFJ4SWrMRNpptwwneVcE6kJmoVtJPN-fmkfDNb7Q,19102
|
93
93
|
vellum_ee/workflows/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
94
94
|
vellum_ee/workflows/server/virtual_file_loader.py,sha256=X_DdNK7MfyOjKWekk6YQpOSCT6klKcdjT6nVJcBH1sM,1481
|
95
95
|
vellum_ee/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -104,7 +104,7 @@ vellum_ee/workflows/tests/local_workflow/display/__init__.py,sha256=xo75Uqb4aErO
|
|
104
104
|
vellum_ee/workflows/tests/local_workflow/display/nodes/__init__.py,sha256=szW_mgOUriyZ6v1vlnevBgkzNi8g83-ihS98UOLHVcE,155
|
105
105
|
vellum_ee/workflows/tests/local_workflow/display/nodes/final_output.py,sha256=Kv92TCREiZsB9531KZYaBIq83uHn7e_ECw_yAbD1qfk,1017
|
106
106
|
vellum_ee/workflows/tests/local_workflow/display/nodes/templating_node.py,sha256=5cankEe1rDZlXKgILFSPbmN0tUZhIdmcFgz_AguXTJc,1229
|
107
|
-
vellum_ee/workflows/tests/local_workflow/display/workflow.py,sha256=
|
107
|
+
vellum_ee/workflows/tests/local_workflow/display/workflow.py,sha256=XJCmx64TCsD2Zt55Q5SISdXSr1NO7n5xenkOtCk0WXI,2151
|
108
108
|
vellum_ee/workflows/tests/local_workflow/inputs.py,sha256=4cgsZBoUbIY0Rs8gknC9yqxQ-sSoULclx_SAm1FT2RA,96
|
109
109
|
vellum_ee/workflows/tests/local_workflow/metadata.json,sha256=rdu3h5qkFZiqhCAMxoyoWyMI0O8QALC5-URvSIW6F00,24
|
110
110
|
vellum_ee/workflows/tests/local_workflow/nodes/__init__.py,sha256=1F6jxUpSKfPXPj4ZZKSbnX6Mg-VwF3euLJSZfGn6xkM,127
|
@@ -119,7 +119,7 @@ vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
|
|
119
119
|
vellum/client/__init__.py,sha256=j6zi0NZ4BMC6JrwckvzMWuG5x8KoOvO4KqsLhvVCa68,117624
|
120
120
|
vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
|
121
121
|
vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
|
122
|
-
vellum/client/core/client_wrapper.py,sha256=
|
122
|
+
vellum/client/core/client_wrapper.py,sha256=r8ZNshVLkA2wiH4k5knCrjqc-qjeEZ06Cpf5iE7nQ-g,1868
|
123
123
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
124
124
|
vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
|
125
125
|
vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
|
@@ -1259,10 +1259,12 @@ vellum/types/workspace_read.py,sha256=9CvgvK8Li8vL6qC5KX7f3-nEHslJ4lw2w07bvXcrjA
|
|
1259
1259
|
vellum/types/workspace_secret_read.py,sha256=Z6QNXHxVHRdrLXSI31KxngePRwJTVoJYMXVbtPQwrxs,159
|
1260
1260
|
vellum/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1261
1261
|
vellum/utils/templating/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1262
|
-
vellum/utils/templating/constants.py,sha256=
|
1263
|
-
vellum/utils/templating/custom_filters.py,sha256=
|
1262
|
+
vellum/utils/templating/constants.py,sha256=8OHMO6WFAEimbIaiHc5gy6s91D7_KvW-vTlEMWwvl_M,711
|
1263
|
+
vellum/utils/templating/custom_filters.py,sha256=XVHriwazejRZmxB_eg4xHgCxl7AiQQ2sx-hRLMmylfU,885
|
1264
1264
|
vellum/utils/templating/exceptions.py,sha256=cDp140PP4OnInW4qAvg3KqiSiF70C71UyEAKRBR1Abo,46
|
1265
|
-
vellum/utils/templating/render.py,sha256=
|
1265
|
+
vellum/utils/templating/render.py,sha256=ooQxCiBMAizPVfwJsIPS2feSBUuoalR1UeJMO0Df-3s,2029
|
1266
|
+
vellum/utils/templating/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1267
|
+
vellum/utils/templating/tests/test_custom_filters.py,sha256=mkJwc7t1gE13SKgPxhF-lN_m2XGCkphCB9Te81dGekI,532
|
1266
1268
|
vellum/utils/typing.py,sha256=wx_daFqD69cYkuJTVnvNrpjhqC3uuhbnyJ9_bIwC9OU,327
|
1267
1269
|
vellum/utils/uuid.py,sha256=Ch6wWRgwICxLxJCTl5iE3EdRlZj2zADR-zUMUtjcMWM,214
|
1268
1270
|
vellum/version.py,sha256=jq-1PlAYxN9AXuaZqbYk9ak27SgE2lw9Ia5gx1b1gVI,76
|
@@ -1282,7 +1284,7 @@ vellum/workflows/emitters/base.py,sha256=D5SADKIvnbgKwIBgYm77jaqvpo1o0rz4MmuX_mu
|
|
1282
1284
|
vellum/workflows/environment/__init__.py,sha256=wGHslgSEZ7Octe4C-hNtl84EFelNimgmWQoi7px4-uw,71
|
1283
1285
|
vellum/workflows/environment/environment.py,sha256=0XhJPBs8YASWmvPx8bkSdCvcbDmzpe9stfs2kgtNDRU,296
|
1284
1286
|
vellum/workflows/errors/__init__.py,sha256=tWGPu5xyAU8gRb8_bl0fL7OfU3wxQ9UH6qVwy4X4P_Q,113
|
1285
|
-
vellum/workflows/errors/types.py,sha256=
|
1287
|
+
vellum/workflows/errors/types.py,sha256=tVW7Il9zalnwWzdoDLqYPIvRTOhXIv6FPORZAbU7n5Q,3640
|
1286
1288
|
vellum/workflows/events/__init__.py,sha256=6pxxceJo2dcaRkWtkDAYlUQZ-PHBQSZytIoyuUK48Qw,759
|
1287
1289
|
vellum/workflows/events/node.py,sha256=uHT6If0esgZ3nLjrjmUPTKf3qbjGhoV_x5YKpjDBDcU,5280
|
1288
1290
|
vellum/workflows/events/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1348,8 +1350,8 @@ vellum/workflows/nodes/core/retry_node/node.py,sha256=loIZJUcCsN0y3mr4pw7f23l4eD
|
|
1348
1350
|
vellum/workflows/nodes/core/retry_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1349
1351
|
vellum/workflows/nodes/core/retry_node/tests/test_node.py,sha256=RM_OHwxrHwyxvlQQBJPqVBxpedFuWQ9h2-Xa3kP75sc,4399
|
1350
1352
|
vellum/workflows/nodes/core/templating_node/__init__.py,sha256=GmyuYo81_A1_Bz6id69ozVFS6FKiuDsZTiA3I6MaL2U,70
|
1351
|
-
vellum/workflows/nodes/core/templating_node/node.py,sha256=
|
1352
|
-
vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py,sha256
|
1353
|
+
vellum/workflows/nodes/core/templating_node/node.py,sha256=Vqlg4L-5XNuIdbZKQe-GEYqTIV7iXNjLO7QIRgz4ujc,3722
|
1354
|
+
vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py,sha256=-53Vh0YOnk8sAcmZ7drdKgBcSCj68DYts5-jFNNsPRE,6755
|
1353
1355
|
vellum/workflows/nodes/core/try_node/__init__.py,sha256=JVD4DrldTIqFQQFrubs9KtWCCc0YCAc7Fzol5ZWIWeM,56
|
1354
1356
|
vellum/workflows/nodes/core/try_node/node.py,sha256=bk2uhYUl10yaPJlOBWxiL7igTUrL_7mM9S2nvsdWB68,4242
|
1355
1357
|
vellum/workflows/nodes/core/try_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1374,12 +1376,12 @@ vellum/workflows/nodes/displayable/bases/tests/test_utils.py,sha256=eqdqbKNRWVMD
|
|
1374
1376
|
vellum/workflows/nodes/displayable/bases/types.py,sha256=C37B2Qh2YP7s7pUjd-EYKc2Zl1TbnCgI_mENuUSb8bo,1706
|
1375
1377
|
vellum/workflows/nodes/displayable/bases/utils.py,sha256=ckMUenSsNkiYmSw6FmjSMHYaCk8Y8_sUjL6lkFFEqts,5412
|
1376
1378
|
vellum/workflows/nodes/displayable/code_execution_node/__init__.py,sha256=0FLWMMktpzSnmBMizQglBpcPrP80fzVsoJwJgf822Cg,76
|
1377
|
-
vellum/workflows/nodes/displayable/code_execution_node/node.py,sha256=
|
1379
|
+
vellum/workflows/nodes/displayable/code_execution_node/node.py,sha256=_yrQn_uLwy8zVW1RjFMoeomDEsbpbbKK7ifMGEBfNlk,9120
|
1378
1380
|
vellum/workflows/nodes/displayable/code_execution_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1379
1381
|
vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1380
1382
|
vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/main.py,sha256=5QsbmkzSlSbcbWTG_JmIqcP-JNJzOPTKxGzdHos19W4,79
|
1381
|
-
vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py,sha256=
|
1382
|
-
vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256=
|
1383
|
+
vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py,sha256=5WHsW_uEKDn1ukM9_O2FsGCYELfONz-2h_kYnNRNYHE,18333
|
1384
|
+
vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256=rdWD1wtxPKHbdHRHEdTeRMSJi9sgAm2t0FqeAWuQHlQ,4534
|
1383
1385
|
vellum/workflows/nodes/displayable/conditional_node/__init__.py,sha256=AS_EIqFdU1F9t8aLmbZU-rLh9ry6LCJ0uj0D8F0L5Uw,72
|
1384
1386
|
vellum/workflows/nodes/displayable/conditional_node/node.py,sha256=Qjfl33gZ3JEgxBA1EgzSUebboGvsARthIxxcQyvx5Gg,1152
|
1385
1387
|
vellum/workflows/nodes/displayable/final_output_node/__init__.py,sha256=G7VXM4OWpubvSJtVkGmMNeqgb9GkM7qZT838eL18XU4,72
|
@@ -1471,8 +1473,8 @@ vellum/workflows/workflows/base.py,sha256=tBivLLLPtMyMi2Bd5WjbwQ2_zZFpG8rNfEidfQ
|
|
1471
1473
|
vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
|
1472
1474
|
vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1473
1475
|
vellum/workflows/workflows/tests/test_base_workflow.py,sha256=dz5F3DuGOk9qUMjmNd-GdEE3320G5ko5nJ6J0QJyVcY,2659
|
1474
|
-
vellum_ai-0.14.
|
1475
|
-
vellum_ai-0.14.
|
1476
|
-
vellum_ai-0.14.
|
1477
|
-
vellum_ai-0.14.
|
1478
|
-
vellum_ai-0.14.
|
1476
|
+
vellum_ai-0.14.2.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
1477
|
+
vellum_ai-0.14.2.dist-info/METADATA,sha256=w083H2Gds-z_b4DPwlYGdnCjD-UXv1q_3CqQAZtSLvI,5407
|
1478
|
+
vellum_ai-0.14.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
1479
|
+
vellum_ai-0.14.2.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
|
1480
|
+
vellum_ai-0.14.2.dist-info/RECORD,,
|
vellum_cli/pull.py
CHANGED
@@ -2,14 +2,14 @@ import io
|
|
2
2
|
import json
|
3
3
|
import os
|
4
4
|
from pathlib import Path
|
5
|
-
from uuid import UUID
|
6
5
|
import zipfile
|
7
|
-
from typing import Optional
|
6
|
+
from typing import Optional
|
8
7
|
|
9
8
|
from dotenv import load_dotenv
|
10
9
|
from pydash import snake_case
|
11
10
|
|
12
11
|
from vellum.client.core.pydantic_utilities import UniversalBaseModel
|
12
|
+
from vellum.utils.uuid import is_valid_uuid
|
13
13
|
from vellum.workflows.vellum_client import create_vellum_client
|
14
14
|
from vellum_cli.config import VellumCliConfig, WorkflowConfig, load_vellum_cli_config
|
15
15
|
from vellum_cli.logger import load_cli_logger
|
@@ -18,14 +18,6 @@ ERROR_LOG_FILE_NAME = "error.log"
|
|
18
18
|
METADATA_FILE_NAME = "metadata.json"
|
19
19
|
|
20
20
|
|
21
|
-
def _is_valid_uuid(val: Union[str, UUID, None]) -> bool:
|
22
|
-
try:
|
23
|
-
UUID(str(val))
|
24
|
-
return True
|
25
|
-
except (ValueError, TypeError):
|
26
|
-
return False
|
27
|
-
|
28
|
-
|
29
21
|
class WorkflowConfigResolutionResult(UniversalBaseModel):
|
30
22
|
workflow_config: Optional[WorkflowConfig] = None
|
31
23
|
pk: Optional[str] = None
|
@@ -88,7 +80,7 @@ def _resolve_workflow_config(
|
|
88
80
|
elif workflow_deployment:
|
89
81
|
module = (
|
90
82
|
f"workflow_{workflow_deployment.split('-')[0]}"
|
91
|
-
if
|
83
|
+
if is_valid_uuid(workflow_deployment)
|
92
84
|
else snake_case(workflow_deployment)
|
93
85
|
)
|
94
86
|
workflow_config = WorkflowConfig(
|
@@ -127,7 +127,7 @@ class WorkflowOutputVellumDisplayOverrides(WorkflowOutputDisplay, WorkflowOutput
|
|
127
127
|
name: str
|
128
128
|
label: str
|
129
129
|
node_id: UUID
|
130
|
-
display_data: NodeDisplayData
|
130
|
+
display_data: Optional[NodeDisplayData] = None
|
131
131
|
target_handle_id: Optional[UUID] = None
|
132
132
|
|
133
133
|
|
@@ -176,6 +176,16 @@ class VellumWorkflowDisplay(
|
|
176
176
|
except IndexError:
|
177
177
|
source_node_display = None
|
178
178
|
|
179
|
+
synthetic_target_handle_id = (
|
180
|
+
str(workflow_output_display.target_handle_id)
|
181
|
+
if workflow_output_display.target_handle_id
|
182
|
+
else str(uuid4_from_hash(f"{self.workflow_id}|target_handle_id|{workflow_output_display.name}"))
|
183
|
+
)
|
184
|
+
synthetic_display_data = (
|
185
|
+
workflow_output_display.display_data.dict()
|
186
|
+
if workflow_output_display.display_data
|
187
|
+
else NodeDisplayData().dict()
|
188
|
+
)
|
179
189
|
nodes.append(
|
180
190
|
{
|
181
191
|
"id": str(final_output_node_id),
|
@@ -183,13 +193,13 @@ class VellumWorkflowDisplay(
|
|
183
193
|
"data": {
|
184
194
|
"label": workflow_output_display.label,
|
185
195
|
"name": workflow_output_display.name,
|
186
|
-
"target_handle_id":
|
196
|
+
"target_handle_id": synthetic_target_handle_id,
|
187
197
|
"output_id": str(workflow_output_display.id),
|
188
198
|
"output_type": inferred_type,
|
189
199
|
"node_input_id": str(node_input.id),
|
190
200
|
},
|
191
201
|
"inputs": [node_input.dict()],
|
192
|
-
"display_data":
|
202
|
+
"display_data": synthetic_display_data,
|
193
203
|
"base": final_output_node_base,
|
194
204
|
"definition": None,
|
195
205
|
}
|
@@ -211,7 +221,7 @@ class VellumWorkflowDisplay(
|
|
211
221
|
"source_node_id": str(source_node_display.node_id),
|
212
222
|
"source_handle_id": str(source_handle_id),
|
213
223
|
"target_node_id": str(workflow_output_display.node_id),
|
214
|
-
"target_handle_id":
|
224
|
+
"target_handle_id": synthetic_target_handle_id,
|
215
225
|
"type": "DEFAULT",
|
216
226
|
}
|
217
227
|
)
|
@@ -372,15 +382,12 @@ class VellumWorkflowDisplay(
|
|
372
382
|
|
373
383
|
output_id = uuid4_from_hash(f"{self.workflow_id}|id|{output.name}")
|
374
384
|
node_id = uuid4_from_hash(f"{self.workflow_id}|node_id|{output.name}")
|
375
|
-
target_handle_id = uuid4_from_hash(f"{self.workflow_id}|target_handle_id|{output.name}")
|
376
385
|
|
377
386
|
return WorkflowOutputVellumDisplay(
|
378
387
|
id=output_id,
|
379
388
|
node_id=node_id,
|
380
389
|
name=output.name,
|
381
390
|
label="Final Output",
|
382
|
-
target_handle_id=target_handle_id,
|
383
|
-
display_data=NodeDisplayData(),
|
384
391
|
)
|
385
392
|
|
386
393
|
def _generate_edge_display(
|
@@ -50,7 +50,5 @@ class WorkflowDisplay(VellumWorkflowDisplay[Workflow]):
|
|
50
50
|
node_id=UUID("f3ef4b2b-fec9-4026-9cc6-e5eac295307f"),
|
51
51
|
name="final-output",
|
52
52
|
label="Final Output",
|
53
|
-
target_handle_id=UUID("3ec34f6e-da48-40d5-a65b-a48fefa75763"),
|
54
|
-
display_data=NodeDisplayData(position=NodeDisplayPosition(x=2750, y=210), width=459, height=234),
|
55
53
|
)
|
56
54
|
}
|
File without changes
|
File without changes
|
File without changes
|