vellum-ai 0.13.27__py3-none-any.whl → 0.13.28__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vellum/client/core/client_wrapper.py +1 -1
- vellum/workflows/descriptors/exceptions.py +2 -0
- vellum/workflows/expressions/accessor.py +4 -3
- vellum/workflows/expressions/begins_with.py +3 -2
- vellum/workflows/expressions/between.py +4 -3
- vellum/workflows/expressions/contains.py +8 -1
- vellum/workflows/expressions/does_not_begin_with.py +3 -2
- vellum/workflows/expressions/does_not_contain.py +4 -1
- vellum/workflows/expressions/does_not_end_with.py +3 -2
- vellum/workflows/expressions/ends_with.py +3 -2
- vellum/workflows/expressions/greater_than.py +3 -2
- vellum/workflows/expressions/greater_than_or_equal_to.py +3 -2
- vellum/workflows/expressions/in_.py +2 -1
- vellum/workflows/expressions/is_blank.py +2 -1
- vellum/workflows/expressions/is_not_blank.py +2 -1
- vellum/workflows/expressions/less_than.py +3 -2
- vellum/workflows/expressions/less_than_or_equal_to.py +3 -2
- vellum/workflows/expressions/not_between.py +4 -3
- vellum/workflows/expressions/not_in.py +2 -1
- vellum/workflows/nodes/bases/base.py +2 -4
- vellum/workflows/nodes/displayable/bases/api_node/node.py +8 -3
- vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +19 -9
- vellum/workflows/ports/port.py +14 -5
- vellum/workflows/utils/vellum_variables.py +3 -0
- {vellum_ai-0.13.27.dist-info → vellum_ai-0.13.28.dist-info}/METADATA +2 -1
- {vellum_ai-0.13.27.dist-info → vellum_ai-0.13.28.dist-info}/RECORD +31 -30
- vellum_cli/push.py +15 -1
- vellum_cli/tests/test_push.py +44 -0
- {vellum_ai-0.13.27.dist-info → vellum_ai-0.13.28.dist-info}/LICENSE +0 -0
- {vellum_ai-0.13.27.dist-info → vellum_ai-0.13.28.dist-info}/WHEEL +0 -0
- {vellum_ai-0.13.27.dist-info → vellum_ai-0.13.28.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.28",
|
22
22
|
}
|
23
23
|
headers["X_API_KEY"] = self.api_key
|
24
24
|
return headers
|
@@ -6,6 +6,7 @@ from pydantic import BaseModel, GetCoreSchemaHandler
|
|
6
6
|
from pydantic_core import core_schema
|
7
7
|
|
8
8
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
9
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
9
10
|
from vellum.workflows.descriptors.utils import resolve_value
|
10
11
|
from vellum.workflows.state.base import BaseState
|
11
12
|
|
@@ -32,13 +33,13 @@ class AccessorExpression(BaseDescriptor[Any]):
|
|
32
33
|
|
33
34
|
if dataclasses.is_dataclass(base):
|
34
35
|
if isinstance(self._field, int):
|
35
|
-
raise
|
36
|
+
raise InvalidExpressionException("Cannot access field by index on a dataclass")
|
36
37
|
|
37
38
|
return getattr(base, self._field)
|
38
39
|
|
39
40
|
if isinstance(base, BaseModel):
|
40
41
|
if isinstance(self._field, int):
|
41
|
-
raise
|
42
|
+
raise InvalidExpressionException("Cannot access field by index on a BaseModel")
|
42
43
|
|
43
44
|
return getattr(base, self._field)
|
44
45
|
|
@@ -49,7 +50,7 @@ class AccessorExpression(BaseDescriptor[Any]):
|
|
49
50
|
index = int(self._field)
|
50
51
|
return base[index]
|
51
52
|
|
52
|
-
raise
|
53
|
+
raise InvalidExpressionException(f"Cannot get field {self._field} from {base}")
|
53
54
|
|
54
55
|
@classmethod
|
55
56
|
def __get_pydantic_core_schema__(
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -23,9 +24,9 @@ class BeginsWithExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
|
|
23
24
|
lhs = resolve_value(self._lhs, state)
|
24
25
|
rhs = resolve_value(self._rhs, state)
|
25
26
|
if not isinstance(lhs, str):
|
26
|
-
raise
|
27
|
+
raise InvalidExpressionException(f"Expected LHS to be a string, got {type(lhs)}")
|
27
28
|
|
28
29
|
if not isinstance(rhs, str):
|
29
|
-
raise
|
30
|
+
raise InvalidExpressionException(f"Expected RHS to be a string, got {type(rhs)}")
|
30
31
|
|
31
32
|
return lhs.startswith(rhs)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -25,14 +26,14 @@ class BetweenExpression(BaseDescriptor[bool], Generic[_V, _S, _E]):
|
|
25
26
|
def resolve(self, state: "BaseState") -> bool:
|
26
27
|
value = resolve_value(self._value, state)
|
27
28
|
if not isinstance(value, (int, float)):
|
28
|
-
raise
|
29
|
+
raise InvalidExpressionException(f"Expected a numeric value, got: {value.__class__.__name__}")
|
29
30
|
|
30
31
|
start = resolve_value(self._start, state)
|
31
32
|
if not isinstance(start, (int, float)):
|
32
|
-
raise
|
33
|
+
raise InvalidExpressionException(f"Expected a numeric start value, got: {start.__class__.__name__}")
|
33
34
|
|
34
35
|
end = resolve_value(self._end, state)
|
35
36
|
if not isinstance(end, (int, float)):
|
36
|
-
raise
|
37
|
+
raise InvalidExpressionException(f"Expected a numeric end value, got: {end.__class__.__name__}")
|
37
38
|
|
38
39
|
return start <= value <= end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
|
+
from vellum.workflows.constants import UNDEF
|
3
4
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
5
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
6
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
7
|
from vellum.workflows.state.base import BaseState
|
6
8
|
|
@@ -23,8 +25,13 @@ class ContainsExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
|
|
23
25
|
# Support any type that implements the in operator
|
24
26
|
# https://app.shortcut.com/vellum/story/4658
|
25
27
|
lhs = resolve_value(self._lhs, state)
|
28
|
+
# assumes that lack of is also false
|
29
|
+
if lhs is UNDEF:
|
30
|
+
return False
|
26
31
|
if not isinstance(lhs, (list, tuple, set, dict, str)):
|
27
|
-
raise
|
32
|
+
raise InvalidExpressionException(
|
33
|
+
f"Expected a LHS that supported `contains`, got `{lhs.__class__.__name__}`"
|
34
|
+
)
|
28
35
|
|
29
36
|
rhs = resolve_value(self._rhs, state)
|
30
37
|
return rhs in lhs
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -23,9 +24,9 @@ class DoesNotBeginWithExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
|
|
23
24
|
lhs = resolve_value(self._lhs, state)
|
24
25
|
rhs = resolve_value(self._rhs, state)
|
25
26
|
if not isinstance(lhs, str):
|
26
|
-
raise
|
27
|
+
raise InvalidExpressionException(f"Expected LHS to be a string, got {type(lhs)}")
|
27
28
|
|
28
29
|
if not isinstance(rhs, str):
|
29
|
-
raise
|
30
|
+
raise InvalidExpressionException(f"Expected RHS to be a string, got {type(rhs)}")
|
30
31
|
|
31
32
|
return not lhs.startswith(rhs)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -24,7 +25,9 @@ class DoesNotContainExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
|
|
24
25
|
# https://app.shortcut.com/vellum/story/4658
|
25
26
|
lhs = resolve_value(self._lhs, state)
|
26
27
|
if not isinstance(lhs, (list, tuple, set, dict, str)):
|
27
|
-
raise
|
28
|
+
raise InvalidExpressionException(
|
29
|
+
f"Expected a LHS that supported `contains`, got `{lhs.__class__.__name__}`"
|
30
|
+
)
|
28
31
|
|
29
32
|
rhs = resolve_value(self._rhs, state)
|
30
33
|
return rhs not in lhs
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -23,9 +24,9 @@ class DoesNotEndWithExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
|
|
23
24
|
lhs = resolve_value(self._lhs, state)
|
24
25
|
rhs = resolve_value(self._rhs, state)
|
25
26
|
if not isinstance(lhs, str):
|
26
|
-
raise
|
27
|
+
raise InvalidExpressionException(f"Expected LHS to be a string, got {type(lhs)}")
|
27
28
|
|
28
29
|
if not isinstance(rhs, str):
|
29
|
-
raise
|
30
|
+
raise InvalidExpressionException(f"Expected RHS to be a string, got {type(rhs)}")
|
30
31
|
|
31
32
|
return not lhs.endswith(rhs)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -23,9 +24,9 @@ class EndsWithExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
|
|
23
24
|
lhs = resolve_value(self._lhs, state)
|
24
25
|
rhs = resolve_value(self._rhs, state)
|
25
26
|
if not isinstance(lhs, str):
|
26
|
-
raise
|
27
|
+
raise InvalidExpressionException(f"Expected LHS to be a string, got {type(lhs)}")
|
27
28
|
|
28
29
|
if not isinstance(rhs, str):
|
29
|
-
raise
|
30
|
+
raise InvalidExpressionException(f"Expected RHS to be a string, got {type(rhs)}")
|
30
31
|
|
31
32
|
return lhs.endswith(rhs)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -24,10 +25,10 @@ class GreaterThanExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
|
|
24
25
|
# https://app.shortcut.com/vellum/story/4658
|
25
26
|
lhs = resolve_value(self._lhs, state)
|
26
27
|
if not isinstance(lhs, (int, float)):
|
27
|
-
raise
|
28
|
+
raise InvalidExpressionException(f"Expected a numeric lhs value, got: {lhs.__class__.__name__}")
|
28
29
|
|
29
30
|
rhs = resolve_value(self._rhs, state)
|
30
31
|
if not isinstance(rhs, (int, float)):
|
31
|
-
raise
|
32
|
+
raise InvalidExpressionException(f"Expected a numeric rhs value, got: {rhs.__class__.__name__}")
|
32
33
|
|
33
34
|
return lhs > rhs
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -24,10 +25,10 @@ class GreaterThanOrEqualToExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
|
|
24
25
|
# https://app.shortcut.com/vellum/story/4658
|
25
26
|
lhs = resolve_value(self._lhs, state)
|
26
27
|
if not isinstance(lhs, (int, float)):
|
27
|
-
raise
|
28
|
+
raise InvalidExpressionException(f"Expected a numeric lhs value, got: {lhs.__class__.__name__}")
|
28
29
|
|
29
30
|
rhs = resolve_value(self._rhs, state)
|
30
31
|
if not isinstance(rhs, (int, float)):
|
31
|
-
raise
|
32
|
+
raise InvalidExpressionException(f"Expected a numeric rhs value, got: {rhs.__class__.__name__}")
|
32
33
|
|
33
34
|
return lhs >= rhs
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -26,6 +27,6 @@ class InExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
|
|
26
27
|
|
27
28
|
rhs = resolve_value(self._rhs, state)
|
28
29
|
if not isinstance(rhs, (list, tuple, set, dict, str)):
|
29
|
-
raise
|
30
|
+
raise InvalidExpressionException(f"Expected a RHS that supported in, got: {rhs.__class__.__name__}")
|
30
31
|
|
31
32
|
return lhs in rhs
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -19,6 +20,6 @@ class IsBlankExpression(BaseDescriptor[bool], Generic[_T]):
|
|
19
20
|
def resolve(self, state: "BaseState") -> bool:
|
20
21
|
expression = resolve_value(self._expression, state)
|
21
22
|
if not isinstance(expression, str):
|
22
|
-
raise
|
23
|
+
raise InvalidExpressionException(f"Expected a string expression, got: {expression.__class__.__name__}")
|
23
24
|
|
24
25
|
return len(expression) == 0
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -19,6 +20,6 @@ class IsNotBlankExpression(BaseDescriptor[bool], Generic[_T]):
|
|
19
20
|
def resolve(self, state: "BaseState") -> bool:
|
20
21
|
expression = resolve_value(self._expression, state)
|
21
22
|
if not isinstance(expression, str):
|
22
|
-
raise
|
23
|
+
raise InvalidExpressionException(f"Expected a string expression, got: {expression.__class__.__name__}")
|
23
24
|
|
24
25
|
return len(expression) != 0
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -24,10 +25,10 @@ class LessThanExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
|
|
24
25
|
# https://app.shortcut.com/vellum/story/4658
|
25
26
|
lhs = resolve_value(self._lhs, state)
|
26
27
|
if not isinstance(lhs, (int, float)):
|
27
|
-
raise
|
28
|
+
raise InvalidExpressionException(f"Expected a numeric lhs value, got: {lhs.__class__.__name__}")
|
28
29
|
|
29
30
|
rhs = resolve_value(self._rhs, state)
|
30
31
|
if not isinstance(rhs, (int, float)):
|
31
|
-
raise
|
32
|
+
raise InvalidExpressionException(f"Expected a numeric rhs value, got: {rhs.__class__.__name__}")
|
32
33
|
|
33
34
|
return lhs < rhs
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -24,10 +25,10 @@ class LessThanOrEqualToExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
|
|
24
25
|
# https://app.shortcut.com/vellum/story/4658
|
25
26
|
lhs = resolve_value(self._lhs, state)
|
26
27
|
if not isinstance(lhs, (int, float)):
|
27
|
-
raise
|
28
|
+
raise InvalidExpressionException(f"Expected a numeric lhs value, got: {lhs.__class__.__name__}")
|
28
29
|
|
29
30
|
rhs = resolve_value(self._rhs, state)
|
30
31
|
if not isinstance(rhs, (int, float)):
|
31
|
-
raise
|
32
|
+
raise InvalidExpressionException(f"Expected a numeric rhs value, got: {rhs.__class__.__name__}")
|
32
33
|
|
33
34
|
return lhs <= rhs
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -25,14 +26,14 @@ class NotBetweenExpression(BaseDescriptor[bool], Generic[_V, _S, _E]):
|
|
25
26
|
def resolve(self, state: "BaseState") -> bool:
|
26
27
|
value = resolve_value(self._value, state)
|
27
28
|
if not isinstance(value, (int, float)):
|
28
|
-
raise
|
29
|
+
raise InvalidExpressionException(f"Expected a numeric value, got: {value.__class__.__name__}")
|
29
30
|
|
30
31
|
start = resolve_value(self._start, state)
|
31
32
|
if not isinstance(start, (int, float)):
|
32
|
-
raise
|
33
|
+
raise InvalidExpressionException(f"Expected a numeric start value, got: {start.__class__.__name__}")
|
33
34
|
|
34
35
|
end = resolve_value(self._end, state)
|
35
36
|
if not isinstance(end, (int, float)):
|
36
|
-
raise
|
37
|
+
raise InvalidExpressionException(f"Expected a numeric end value, got: {end.__class__.__name__}")
|
37
38
|
|
38
39
|
return value < start or value > end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Generic, TypeVar, Union
|
2
2
|
|
3
3
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
4
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
4
5
|
from vellum.workflows.descriptors.utils import resolve_value
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
@@ -26,6 +27,6 @@ class NotInExpression(BaseDescriptor[bool], Generic[LHS, RHS]):
|
|
26
27
|
|
27
28
|
rhs = resolve_value(self._rhs, state)
|
28
29
|
if not isinstance(rhs, (list, tuple, set, dict, str)):
|
29
|
-
raise
|
30
|
+
raise InvalidExpressionException(f"Expected a RHS that supported contains, got: {rhs.__class__.__name__}")
|
30
31
|
|
31
32
|
return lhs not in rhs
|
@@ -255,17 +255,15 @@ class BaseNode(Generic[StateType], metaclass=BaseNodeMeta):
|
|
255
255
|
return False
|
256
256
|
|
257
257
|
if cls.merge_behavior == MergeBehavior.AWAIT_ATTRIBUTES:
|
258
|
-
is_ready = True
|
259
258
|
for descriptor in cls.node_class:
|
260
259
|
if not descriptor.instance:
|
261
260
|
continue
|
262
261
|
|
263
262
|
resolved_value = resolve_value(descriptor.instance, state, path=descriptor.name)
|
264
263
|
if is_unresolved(resolved_value):
|
265
|
-
|
266
|
-
break
|
264
|
+
return False
|
267
265
|
|
268
|
-
return
|
266
|
+
return True
|
269
267
|
|
270
268
|
if cls.merge_behavior == MergeBehavior.AWAIT_ANY:
|
271
269
|
return True
|
@@ -3,6 +3,7 @@ from typing import Any, Dict, Generic, Optional, Union
|
|
3
3
|
from requests import Request, RequestException, Session
|
4
4
|
from requests.exceptions import JSONDecodeError
|
5
5
|
|
6
|
+
from vellum.client import ApiError
|
6
7
|
from vellum.client.types.vellum_secret import VellumSecret as ClientVellumSecret
|
7
8
|
from vellum.workflows.constants import APIRequestMethod
|
8
9
|
from vellum.workflows.errors.types import WorkflowErrorCode
|
@@ -83,9 +84,13 @@ class BaseAPINode(BaseNode, Generic[StateType]):
|
|
83
84
|
|
84
85
|
def _vellum_execute_api(self, bearer_token, data, headers, method, url):
|
85
86
|
client_vellum_secret = ClientVellumSecret(name=bearer_token.name) if bearer_token else None
|
86
|
-
|
87
|
-
|
88
|
-
|
87
|
+
try:
|
88
|
+
vellum_response = self._context.vellum_client.execute_api(
|
89
|
+
url=url, method=method.value, body=data, headers=headers, bearer_token=client_vellum_secret
|
90
|
+
)
|
91
|
+
except ApiError as e:
|
92
|
+
NodeException(f"Failed to prepare HTTP request: {e}", code=WorkflowErrorCode.NODE_EXECUTION)
|
93
|
+
|
89
94
|
return self.Outputs(
|
90
95
|
json=vellum_response.json_,
|
91
96
|
headers={header: value for header, value in vellum_response.headers.items()},
|
@@ -40,16 +40,14 @@ class BasePromptNode(BaseNode, Generic[StateType]):
|
|
40
40
|
try:
|
41
41
|
prompt_event_stream = self._get_prompt_event_stream()
|
42
42
|
except ApiError as e:
|
43
|
-
|
44
|
-
raise NodeException(
|
45
|
-
message=e.body.get("detail", "Failed to execute prompt"),
|
46
|
-
code=WorkflowErrorCode.INVALID_INPUTS,
|
47
|
-
) from e
|
43
|
+
self._handle_api_error(e)
|
48
44
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
)
|
45
|
+
# We don't use the INITIATED event anyway, so we can just skip it
|
46
|
+
# and use the exception handling to catch other api level errors
|
47
|
+
try:
|
48
|
+
next(prompt_event_stream)
|
49
|
+
except ApiError as e:
|
50
|
+
self._handle_api_error(e)
|
53
51
|
|
54
52
|
outputs: Optional[List[PromptOutput]] = None
|
55
53
|
for event in prompt_event_stream:
|
@@ -65,3 +63,15 @@ class BasePromptNode(BaseNode, Generic[StateType]):
|
|
65
63
|
raise NodeException.of(workflow_error)
|
66
64
|
|
67
65
|
return outputs
|
66
|
+
|
67
|
+
def _handle_api_error(self, e: ApiError):
|
68
|
+
if e.status_code and e.status_code >= 400 and e.status_code < 500 and isinstance(e.body, dict):
|
69
|
+
raise NodeException(
|
70
|
+
message=e.body.get("detail", "Failed to execute prompt"),
|
71
|
+
code=WorkflowErrorCode.INVALID_INPUTS,
|
72
|
+
) from e
|
73
|
+
|
74
|
+
raise NodeException(
|
75
|
+
message="Failed to execute prompt",
|
76
|
+
code=WorkflowErrorCode.INTERNAL_ERROR,
|
77
|
+
) from e
|
vellum/workflows/ports/port.py
CHANGED
@@ -4,7 +4,10 @@ from pydantic import GetCoreSchemaHandler
|
|
4
4
|
from pydantic_core import core_schema
|
5
5
|
|
6
6
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
7
|
+
from vellum.workflows.descriptors.exceptions import InvalidExpressionException
|
7
8
|
from vellum.workflows.edges.edge import Edge
|
9
|
+
from vellum.workflows.errors.types import WorkflowErrorCode
|
10
|
+
from vellum.workflows.exceptions import NodeException
|
8
11
|
from vellum.workflows.graph import Graph, GraphTarget
|
9
12
|
from vellum.workflows.state.base import BaseState
|
10
13
|
from vellum.workflows.types.core import ConditionType
|
@@ -82,11 +85,17 @@ class Port:
|
|
82
85
|
return Port(condition_type=ConditionType.ELSE, fork_state=fork_state)
|
83
86
|
|
84
87
|
def resolve_condition(self, state: BaseState) -> bool:
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
88
|
+
try:
|
89
|
+
if self._condition is None:
|
90
|
+
return False
|
91
|
+
|
92
|
+
value = self._condition.resolve(state)
|
93
|
+
return bool(value)
|
94
|
+
except InvalidExpressionException as e:
|
95
|
+
raise NodeException(
|
96
|
+
message=f"Failed to resolve condition for port `{self.name}`: {e}",
|
97
|
+
code=WorkflowErrorCode.INVALID_INPUTS,
|
98
|
+
) from e
|
90
99
|
|
91
100
|
def serialize(self) -> dict:
|
92
101
|
return {
|
@@ -45,6 +45,9 @@ def primitive_type_to_vellum_variable_type(type_: Union[Type, BaseDescriptor]) -
|
|
45
45
|
]
|
46
46
|
if types == actual_types_with_explicit_ref:
|
47
47
|
return "JSON"
|
48
|
+
# Number now supports float and int
|
49
|
+
elif types == [float, int]:
|
50
|
+
return "NUMBER"
|
48
51
|
raise ValueError(f"Expected Descriptor to only have one type, got {types}")
|
49
52
|
|
50
53
|
type_ = type_.types[0]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: vellum-ai
|
3
|
-
Version: 0.13.
|
3
|
+
Version: 0.13.28
|
4
4
|
Summary:
|
5
5
|
License: MIT
|
6
6
|
Requires-Python: >=3.9,<4.0
|
@@ -37,6 +37,7 @@ Requires-Dist: pyyaml (==6.0.1)
|
|
37
37
|
Requires-Dist: requests (==2.32.3)
|
38
38
|
Requires-Dist: tomli (==2.0.2)
|
39
39
|
Requires-Dist: typing_extensions (>=4.0.0)
|
40
|
+
Project-URL: Repository, https://github.com/vellum-ai/vellum-python-sdks
|
40
41
|
Description-Content-Type: text/markdown
|
41
42
|
|
42
43
|
<p align="center">
|
@@ -7,14 +7,14 @@ 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
9
|
vellum_cli/pull.py,sha256=7yvg4oBOgsbBEsgXtCpYlNR4AOR8hPICamY-4HI-3kM,9031
|
10
|
-
vellum_cli/push.py,sha256=
|
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
|
13
13
|
vellum_cli/tests/test_config.py,sha256=uvKGDc8BoVyT9_H0Z-g8469zVxomn6Oi3Zj-vK7O_wU,2631
|
14
14
|
vellum_cli/tests/test_main.py,sha256=qDZG-aQauPwBwM6A2DIu1494n47v3pL28XakTbLGZ-k,272
|
15
15
|
vellum_cli/tests/test_ping.py,sha256=QtbhYKMYn1DFnDyBij2mkQO32j9KOpZ5Pf0yek7k_Ao,1284
|
16
16
|
vellum_cli/tests/test_pull.py,sha256=JURmgGs5lSnpzefSx4K13eF2swv7O8OF86-4df81Zjo,25241
|
17
|
-
vellum_cli/tests/test_push.py,sha256=
|
17
|
+
vellum_cli/tests/test_push.py,sha256=zDZfSQCHCdKqSfGVHGRgX9VPm-H7EW5gwMf55dm_PFg,23438
|
18
18
|
vellum_ee/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
19
|
vellum_ee/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
20
|
vellum_ee/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -116,7 +116,7 @@ vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
|
|
116
116
|
vellum/client/__init__.py,sha256=j6zi0NZ4BMC6JrwckvzMWuG5x8KoOvO4KqsLhvVCa68,117624
|
117
117
|
vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
|
118
118
|
vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
|
119
|
-
vellum/client/core/client_wrapper.py,sha256=
|
119
|
+
vellum/client/core/client_wrapper.py,sha256=K05OPis1DlTJSg2W24og49fZhiG0aW5aExROjEOtIAA,1869
|
120
120
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
121
121
|
vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
|
122
122
|
vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
|
@@ -1269,6 +1269,7 @@ vellum/workflows/constants.py,sha256=Z0W4YlqfSlSgWC11PrVUPs6ZOBeIaQ78E_90J1hohiw
|
|
1269
1269
|
vellum/workflows/context.py,sha256=R8qdsFbD_0p7B6PWnyvSrZ_aOgMtGw-_uk0P0UAmwLA,1230
|
1270
1270
|
vellum/workflows/descriptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1271
1271
|
vellum/workflows/descriptors/base.py,sha256=gSib3vJpcI_UC8y8jhdp-hOK3_TGTF-SuwdhxF6x5iQ,14332
|
1272
|
+
vellum/workflows/descriptors/exceptions.py,sha256=gUy4UD9JFUKSeQnQpeuDSLiRqWjWiIsxLahB7p_q3JY,54
|
1272
1273
|
vellum/workflows/descriptors/tests/test_utils.py,sha256=63w1P6PELNhWzpg1BqL8y2XQZ8XRt0RUkHgLcsXyOQE,4592
|
1273
1274
|
vellum/workflows/descriptors/utils.py,sha256=nE51MR0KMy3SVHPBg0wjJ3CSJBTLM3tZnVUC_enQEIw,3826
|
1274
1275
|
vellum/workflows/edges/__init__.py,sha256=wSkmAnz9xyi4vZwtDbKxwlplt2skD7n3NsxkvR_pUus,50
|
@@ -1287,33 +1288,33 @@ vellum/workflows/events/types.py,sha256=cjRE8WL8tYCFradd9NOGl_H0mN3LiWWnA1uHmyT2
|
|
1287
1288
|
vellum/workflows/events/workflow.py,sha256=lveoWXtVRLjdO_nu0z6VlKeTqlGimogamiFR-jYihlE,5184
|
1288
1289
|
vellum/workflows/exceptions.py,sha256=l-FLGvXywxg6ivolCts71b8pcsYAWoB1cmUR4Jx7N8g,614
|
1289
1290
|
vellum/workflows/expressions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1290
|
-
vellum/workflows/expressions/accessor.py,sha256=
|
1291
|
+
vellum/workflows/expressions/accessor.py,sha256=ItZF7fMLzVTqsdAiaXb5SiDupXmX0X9xbIus1W6hRds,1870
|
1291
1292
|
vellum/workflows/expressions/and_.py,sha256=I7lNqrUM3-m_5hmjjiMhaHhJtKcLj39kEFVWPDOqwfo,916
|
1292
|
-
vellum/workflows/expressions/begins_with.py,sha256=
|
1293
|
-
vellum/workflows/expressions/between.py,sha256=
|
1293
|
+
vellum/workflows/expressions/begins_with.py,sha256=FnWsQXbENm0ZwkfEP7dR8Qx4_MMrzj6C1yqAV2KaNHw,1123
|
1294
|
+
vellum/workflows/expressions/between.py,sha256=dVeddT6YA91eOAlE1Utg7C7gnCiYE7WP-dg17yXUeAY,1492
|
1294
1295
|
vellum/workflows/expressions/coalesce_expression.py,sha256=Fyx2cvi715hPhi2OEfH3D0gD_smQIa2aDwnjr7q2Ngs,1186
|
1295
|
-
vellum/workflows/expressions/contains.py,sha256=
|
1296
|
-
vellum/workflows/expressions/does_not_begin_with.py,sha256=
|
1297
|
-
vellum/workflows/expressions/does_not_contain.py,sha256=
|
1298
|
-
vellum/workflows/expressions/does_not_end_with.py,sha256=
|
1296
|
+
vellum/workflows/expressions/contains.py,sha256=gYpQQlsY8YxBWfisfCI4I_mc-IW7f6U4ZTpuN3WZtMA,1313
|
1297
|
+
vellum/workflows/expressions/does_not_begin_with.py,sha256=qcnIJsxg4Jt82i2L-PW6ZhKP3C-OlEiXbiIgwHQc5RE,1137
|
1298
|
+
vellum/workflows/expressions/does_not_contain.py,sha256=B4m23jJiKBM6ANVtA4WfdUnT-MdQGxVVgR14ypgYBIs,1195
|
1299
|
+
vellum/workflows/expressions/does_not_end_with.py,sha256=idw2OSuIk02XwBM5CXYOESf655mRrdBREjeinZ5tmVQ,1131
|
1299
1300
|
vellum/workflows/expressions/does_not_equal.py,sha256=LNiCibRZZIxaIrwotjW3SIsKYHWR7BpOItFI-x5KuKU,764
|
1300
|
-
vellum/workflows/expressions/ends_with.py,sha256=
|
1301
|
+
vellum/workflows/expressions/ends_with.py,sha256=FkWZjAudc_DFM-fK-A3_tr6WXavfs_Qi7F6JtVgMglw,1117
|
1301
1302
|
vellum/workflows/expressions/equals.py,sha256=gbI6BKQR7cLQih226-ge_BFSLprgEjqbdiIxo7WFg_E,758
|
1302
|
-
vellum/workflows/expressions/greater_than.py,sha256=
|
1303
|
-
vellum/workflows/expressions/greater_than_or_equal_to.py,sha256=
|
1304
|
-
vellum/workflows/expressions/in_.py,sha256=
|
1305
|
-
vellum/workflows/expressions/is_blank.py,sha256=
|
1303
|
+
vellum/workflows/expressions/greater_than.py,sha256=fTM2YF3FY_eOkRtGpgVWcv8qNt4K3lazONUIqcD8oe8,1263
|
1304
|
+
vellum/workflows/expressions/greater_than_or_equal_to.py,sha256=sazL_-Jsgjo4jcQeE-6EC0BFHZACriaYMQH4rn0dqEo,1275
|
1305
|
+
vellum/workflows/expressions/in_.py,sha256=RgiAIFntXGN4eWoOVBj1gqLymnBxSiw5hYD3TngF3dk,1123
|
1306
|
+
vellum/workflows/expressions/is_blank.py,sha256=vOOmK5poXmiNRVH7MR0feIFnL4rwKn7vmmTkJ9TcfVU,904
|
1306
1307
|
vellum/workflows/expressions/is_nil.py,sha256=dtgY9Czm3slk45weARspwtfhQmVh0BIUsPOECrATLrA,740
|
1307
|
-
vellum/workflows/expressions/is_not_blank.py,sha256=
|
1308
|
+
vellum/workflows/expressions/is_not_blank.py,sha256=GJNTe8TKIbh4RwWPFuPwEQw0hbxg2MobHg8bcal4xWU,911
|
1308
1309
|
vellum/workflows/expressions/is_not_nil.py,sha256=M5Qhtp_H07PORjFN2WapwA1Njp_KaANmLWbfckSSscM,761
|
1309
1310
|
vellum/workflows/expressions/is_not_null.py,sha256=EoHXFgZScKP_BM2a5Z7YFQN6l7RMEtzs5x5nlvaSST8,671
|
1310
1311
|
vellum/workflows/expressions/is_not_undefined.py,sha256=8NGwA0wZP_aHRy5qJOtaNhRCJyXKekwBNJalSk6Rdmo,727
|
1311
1312
|
vellum/workflows/expressions/is_null.py,sha256=C75ALGlG_sTGcxI46tm9HtgPVfJ7DwTIyKzX8qtEiDU,660
|
1312
1313
|
vellum/workflows/expressions/is_undefined.py,sha256=c9Oc1fdp911fQQ8WMG2L-TeUSqz1wF8cOTuLutJKbe8,716
|
1313
|
-
vellum/workflows/expressions/less_than.py,sha256=
|
1314
|
-
vellum/workflows/expressions/less_than_or_equal_to.py,sha256=
|
1315
|
-
vellum/workflows/expressions/not_between.py,sha256=
|
1316
|
-
vellum/workflows/expressions/not_in.py,sha256=
|
1314
|
+
vellum/workflows/expressions/less_than.py,sha256=BcfkUH6Bb2inwR8jILn1hebUiyC74foVijBA-JymwT0,1260
|
1315
|
+
vellum/workflows/expressions/less_than_or_equal_to.py,sha256=4i1FR6FzlKam29cZPPnXUqACslO242Ww-wZZY4CEK6A,1272
|
1316
|
+
vellum/workflows/expressions/not_between.py,sha256=ZtRJeJDSSlOvajL8YoBoh5o_khjIn9xSSeQCnXYbHFE,1506
|
1317
|
+
vellum/workflows/expressions/not_in.py,sha256=pFvwkFPsn3WJw61ssFgM2U1dqWEeglfz4FVT4xwm5Mc,1144
|
1317
1318
|
vellum/workflows/expressions/or_.py,sha256=s-8YdMSSCDS2yijR38kguwok3iqmDMMgDYKV93b4O4s,914
|
1318
1319
|
vellum/workflows/graph/__init__.py,sha256=3sHlay5d_-uD7j3QJXiGl0WHFZZ_QScRvgyDhN2GhHY,74
|
1319
1320
|
vellum/workflows/graph/graph.py,sha256=GGR8cGpSuNWPIiTWNWsj6l70upb5nIxAyFcn7VdaJIs,5506
|
@@ -1324,7 +1325,7 @@ vellum/workflows/inputs/base.py,sha256=1kMgr0WqCYdWUqgFvgSoAMw2067FAlgwhGXLgbIOr
|
|
1324
1325
|
vellum/workflows/logging.py,sha256=_a217XogktV4Ncz6xKFz7WfYmZAzkfVRVuC0rWob8ls,437
|
1325
1326
|
vellum/workflows/nodes/__init__.py,sha256=aVdQVv7Y3Ro3JlqXGpxwaU2zrI06plDHD2aumH5WUIs,1157
|
1326
1327
|
vellum/workflows/nodes/bases/__init__.py,sha256=cniHuz_RXdJ4TQgD8CBzoiKDiPxg62ErdVpCbWICX64,58
|
1327
|
-
vellum/workflows/nodes/bases/base.py,sha256=
|
1328
|
+
vellum/workflows/nodes/bases/base.py,sha256=jKgneygDa47BkuApl8VgvYItT3DMFuaqO3RetJwqPdg,14116
|
1328
1329
|
vellum/workflows/nodes/bases/base_adornment_node.py,sha256=eFTgsPCYb3eyGS0-kw7C6crFnwFx437R5wh9-8bWYts,2905
|
1329
1330
|
vellum/workflows/nodes/bases/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1330
1331
|
vellum/workflows/nodes/bases/tests/test_base_node.py,sha256=51CueFVty9XYASC0rKr1cXWejho5WElmhfhp6cCONy0,3811
|
@@ -1357,9 +1358,9 @@ vellum/workflows/nodes/displayable/api_node/tests/__init__.py,sha256=47DEQpj8HBS
|
|
1357
1358
|
vellum/workflows/nodes/displayable/api_node/tests/test_api_node.py,sha256=yo3zTMRxgpSdWmJ68X610A5rrtCchyfqhcDd2X-GJiU,1249
|
1358
1359
|
vellum/workflows/nodes/displayable/bases/__init__.py,sha256=0mWIx3qUrzllV7jqt7wN03vWGMuI1WrrLZeMLT2Cl2c,304
|
1359
1360
|
vellum/workflows/nodes/displayable/bases/api_node/__init__.py,sha256=1jwx4WC358CLA1jgzl_UD-rZmdMm2v9Mps39ndwCD7U,64
|
1360
|
-
vellum/workflows/nodes/displayable/bases/api_node/node.py,sha256=
|
1361
|
+
vellum/workflows/nodes/displayable/bases/api_node/node.py,sha256=TeVsAhUPEx_lbiyhGcWarqBKZeJJZAJx8mwym9qhwVs,3994
|
1361
1362
|
vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py,sha256=Org3xTvgp1pA0uUXFfnJr29D3HzCey2lEdYF4zbIUgo,70
|
1362
|
-
vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=
|
1363
|
+
vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=cKsNziwWJ9jUjS578I5dIka-zmsXz94hYZR3Cofm8aE,3140
|
1363
1364
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py,sha256=Hl35IAoepRpE-j4cALaXVJIYTYOF3qszyVbxTj4kS1s,82
|
1364
1365
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/constants.py,sha256=fnjiRWLoRlC4Puo5oQcpZD5Hd-EesxsAo9l5tGAkpZQ,270
|
1365
1366
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=UrmI8NkNJFGq9f59gD12S1e8D_R3ROHc934JmtfQk9I,6841
|
@@ -1416,7 +1417,7 @@ vellum/workflows/outputs/__init__.py,sha256=AyZ4pRh_ACQIGvkf0byJO46EDnSix1ZCAXfv
|
|
1416
1417
|
vellum/workflows/outputs/base.py,sha256=Wu48tqyQoxpflBUcwzKeZjSVp1LPKrBwuIvnx__9H90,8459
|
1417
1418
|
vellum/workflows/ports/__init__.py,sha256=bZuMt-R7z5bKwpu4uPW7LlJeePOQWmCcDSXe5frUY5g,101
|
1418
1419
|
vellum/workflows/ports/node_ports.py,sha256=g4A-8iUAvEJSkaWppbvzAR8XU02R9U-qLN4rP2Kq4Aw,2743
|
1419
|
-
vellum/workflows/ports/port.py,sha256=
|
1420
|
+
vellum/workflows/ports/port.py,sha256=eI2SOZPZ5rsC3jMsxW6Rbn0NpaYQsrR7AapiIbbiy8Q,3635
|
1420
1421
|
vellum/workflows/ports/utils.py,sha256=pEjVNJKw9LhD_cFN-o0MWBOW2ejno7jv26qqzjLxwS4,1662
|
1421
1422
|
vellum/workflows/references/__init__.py,sha256=glHFC1VfXmcbNvH5VzFbkT03d8_D7MMcvEcsUBrzLIs,591
|
1422
1423
|
vellum/workflows/references/constant.py,sha256=6yUT4q1sMj1hkI_tzzQ9AYcmeeDYFUNCqUq_W2DN0S8,540
|
@@ -1460,13 +1461,13 @@ vellum/workflows/utils/tests/test_names.py,sha256=aOqpyvMsOEK_9mg_-yaNxQDW7QQfwq
|
|
1460
1461
|
vellum/workflows/utils/tests/test_uuids.py,sha256=i77ABQ0M3S-aFLzDXHJq_yr5FPkJEWCMBn1HJ3DObrE,437
|
1461
1462
|
vellum/workflows/utils/tests/test_vellum_variables.py,sha256=6H-BpmbIEmVRO75QQ3Rfy4bEUMMP2qwGzx2Gp1uXbfw,879
|
1462
1463
|
vellum/workflows/utils/uuids.py,sha256=DFzPv9RCvsKhvdTEIQyfSek2A31D6S_QcmeLPbgrgTY,739
|
1463
|
-
vellum/workflows/utils/vellum_variables.py,sha256=
|
1464
|
+
vellum/workflows/utils/vellum_variables.py,sha256=fC2aSLvlS31D15dOWu43LBRR0QsgUKNXBiCUvvaLXSs,3231
|
1464
1465
|
vellum/workflows/vellum_client.py,sha256=ODrq_TSl-drX2aezXegf7pizpWDVJuTXH-j6528t75s,683
|
1465
1466
|
vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
|
1466
1467
|
vellum/workflows/workflows/base.py,sha256=uYT0TQnEDtVaH3pErq785FhxxEEmk7C5ZGfuSO3QK8c,18537
|
1467
1468
|
vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
|
1468
|
-
vellum_ai-0.13.
|
1469
|
-
vellum_ai-0.13.
|
1470
|
-
vellum_ai-0.13.
|
1471
|
-
vellum_ai-0.13.
|
1472
|
-
vellum_ai-0.13.
|
1469
|
+
vellum_ai-0.13.28.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
1470
|
+
vellum_ai-0.13.28.dist-info/METADATA,sha256=wrTghMo3kpO_xtsK1SbioWmx3p_ZdG0vifuj57JrZvs,5408
|
1471
|
+
vellum_ai-0.13.28.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
1472
|
+
vellum_ai-0.13.28.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
|
1473
|
+
vellum_ai-0.13.28.dist-info/RECORD,,
|
vellum_cli/push.py
CHANGED
@@ -53,7 +53,16 @@ def push_command(
|
|
53
53
|
workflow_configs = [w for w in workflow_configs if w.workspace == workspace]
|
54
54
|
|
55
55
|
if len(workflow_configs) == 0:
|
56
|
-
|
56
|
+
if module and module_exists(module):
|
57
|
+
new_config = WorkflowConfig(
|
58
|
+
module=module,
|
59
|
+
workflow_sandbox_id=workflow_sandbox_id,
|
60
|
+
workspace=workspace or DEFAULT_WORKSPACE_CONFIG.name,
|
61
|
+
)
|
62
|
+
config.workflows.append(new_config)
|
63
|
+
workflow_configs = [new_config]
|
64
|
+
else:
|
65
|
+
raise ValueError(f"No workflow config for '{module}' found in project to push.")
|
57
66
|
|
58
67
|
if len(workflow_configs) > 1:
|
59
68
|
raise ValueError("Multiple workflows found in project to push. Pushing only a single workflow is supported.")
|
@@ -241,3 +250,8 @@ Visit at: https://app.vellum.ai/workflow-sandboxes/{response.workflow_sandbox_id
|
|
241
250
|
|
242
251
|
config.save()
|
243
252
|
logger.info("Updated vellum.lock.json file.")
|
253
|
+
|
254
|
+
|
255
|
+
def module_exists(module_name: str) -> bool:
|
256
|
+
module_path = os.path.join(os.getcwd(), *module_name.split("."))
|
257
|
+
return os.path.exists(module_path) and os.path.isdir(module_path)
|
vellum_cli/tests/test_push.py
CHANGED
@@ -589,3 +589,47 @@ MY_OTHER_VELLUM_API_KEY=aaabbbcccddd
|
|
589
589
|
assert lock_file_content["workflows"][1]["module"] == module
|
590
590
|
assert lock_file_content["workflows"][1]["workflow_sandbox_id"] == second_workflow_sandbox_id
|
591
591
|
assert lock_file_content["workflows"][1]["workspace"] == "my_other_workspace"
|
592
|
+
|
593
|
+
|
594
|
+
def test_push__create_new_config_for_existing_module(mock_module, vellum_client):
|
595
|
+
# GIVEN an empty config (no workflows configured)
|
596
|
+
temp_dir = mock_module.temp_dir
|
597
|
+
module = mock_module.module
|
598
|
+
# GIVEN multiple workflows configured
|
599
|
+
mock_module.set_pyproject_toml({"workflows": [{"module": "examples.mock"}, {"module": "examples.mock2"}]})
|
600
|
+
|
601
|
+
# AND a workflow exists in the module successfully
|
602
|
+
workflow_py_file_content = _ensure_workflow_py(temp_dir, module)
|
603
|
+
|
604
|
+
# AND the push API call returns successfully
|
605
|
+
new_workflow_sandbox_id = str(uuid4())
|
606
|
+
vellum_client.workflows.push.return_value = WorkflowPushResponse(
|
607
|
+
workflow_sandbox_id=new_workflow_sandbox_id,
|
608
|
+
)
|
609
|
+
|
610
|
+
# WHEN calling `vellum push` with a module that exists but isn't in config
|
611
|
+
runner = CliRunner()
|
612
|
+
result = runner.invoke(cli_main, ["workflows", "push", module])
|
613
|
+
|
614
|
+
# THEN it should succeed
|
615
|
+
assert result.exit_code == 0, result.output
|
616
|
+
|
617
|
+
# AND we should have called the push API with the correct args
|
618
|
+
vellum_client.workflows.push.assert_called_once()
|
619
|
+
call_args = vellum_client.workflows.push.call_args.kwargs
|
620
|
+
assert json.loads(call_args["exec_config"])["workflow_raw_data"]["definition"]["name"] == "ExampleWorkflow"
|
621
|
+
assert call_args["workflow_sandbox_id"] is None # Should be None since it's a new config
|
622
|
+
assert call_args["artifact"].name == f"{module.replace('.', '__')}.tar.gz"
|
623
|
+
|
624
|
+
# AND the files in the artifact should be correct
|
625
|
+
extracted_files = _extract_tar_gz(call_args["artifact"].read())
|
626
|
+
assert extracted_files["workflow.py"] == workflow_py_file_content
|
627
|
+
|
628
|
+
# AND check that lockfile was updated with new config
|
629
|
+
with open(os.path.join(temp_dir, "vellum.lock.json")) as f:
|
630
|
+
lock_file_content = json.load(f)
|
631
|
+
new_configs = [w for w in lock_file_content["workflows"] if w["module"] == module]
|
632
|
+
assert len(new_configs) == 1 # Should only create one config
|
633
|
+
new_config = new_configs[0]
|
634
|
+
assert new_config["workflow_sandbox_id"] == new_workflow_sandbox_id
|
635
|
+
assert new_config["workspace"] == "default"
|
File without changes
|
File without changes
|
File without changes
|