vellum-ai 0.14.65__py3-none-any.whl → 0.14.67__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 +1 -1
- vellum/client/core/client_wrapper.py +1 -1
- vellum/client/reference.md +2767 -0
- vellum/client/types/document_read.py +0 -1
- vellum/client/types/folder_entity_prompt_sandbox_data.py +1 -0
- vellum/client/types/folder_entity_workflow_sandbox_data.py +1 -0
- vellum/workflows/expressions/accessor.py +22 -5
- vellum/workflows/expressions/tests/test_accessor.py +189 -0
- vellum/workflows/nodes/bases/base.py +30 -39
- vellum/workflows/nodes/bases/tests/test_base_node.py +48 -2
- vellum/workflows/nodes/displayable/api_node/node.py +3 -1
- vellum/workflows/nodes/displayable/api_node/tests/test_api_node.py +32 -0
- vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +28 -0
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py +26 -23
- vellum/workflows/nodes/displayable/conditional_node/node.py +1 -2
- vellum/workflows/nodes/displayable/final_output_node/node.py +2 -0
- vellum/workflows/nodes/displayable/inline_prompt_node/node.py +4 -14
- vellum/workflows/nodes/displayable/search_node/node.py +8 -0
- vellum/workflows/nodes/displayable/search_node/tests/test_node.py +19 -0
- vellum/workflows/nodes/experimental/tool_calling_node/utils.py +4 -13
- vellum/workflows/runner/runner.py +13 -17
- vellum/workflows/state/base.py +0 -4
- {vellum_ai-0.14.65.dist-info → vellum_ai-0.14.67.dist-info}/METADATA +2 -2
- {vellum_ai-0.14.65.dist-info → vellum_ai-0.14.67.dist-info}/RECORD +33 -30
- vellum_cli/image_push.py +62 -7
- vellum_cli/pull.py +38 -9
- vellum_cli/tests/test_image_push_error_handling.py +184 -0
- vellum_cli/tests/test_pull.py +12 -9
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py +661 -0
- vellum_ee/workflows/display/utils/expressions.py +17 -0
- {vellum_ai-0.14.65.dist-info → vellum_ai-0.14.67.dist-info}/LICENSE +0 -0
- {vellum_ai-0.14.65.dist-info → vellum_ai-0.14.67.dist-info}/WHEEL +0 -0
- {vellum_ai-0.14.65.dist-info → vellum_ai-0.14.67.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,184 @@
|
|
1
|
+
import subprocess
|
2
|
+
from unittest.mock import patch
|
3
|
+
from uuid import uuid4
|
4
|
+
|
5
|
+
from click.testing import CliRunner
|
6
|
+
|
7
|
+
from vellum.client.core.api_error import ApiError
|
8
|
+
from vellum_cli import main as cli_main
|
9
|
+
|
10
|
+
|
11
|
+
@patch("subprocess.run")
|
12
|
+
@patch("docker.from_env")
|
13
|
+
def test_image_push_docker_service_token_401_error(mock_docker_from_env, mock_run, vellum_client, monkeypatch):
|
14
|
+
monkeypatch.setenv("VELLUM_API_URL", "https://api.vellum.ai")
|
15
|
+
monkeypatch.setenv("VELLUM_API_KEY", "123456abcdef")
|
16
|
+
|
17
|
+
mock_docker_client = mock_docker_from_env.return_value
|
18
|
+
mock_docker_client.images.get.return_value.id = "test-image-id"
|
19
|
+
|
20
|
+
mock_run.side_effect = [
|
21
|
+
subprocess.CompletedProcess(
|
22
|
+
args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
|
23
|
+
),
|
24
|
+
]
|
25
|
+
|
26
|
+
vellum_client.container_images.docker_service_token.side_effect = ApiError(status_code=401, body="Unauthorized")
|
27
|
+
|
28
|
+
runner = CliRunner()
|
29
|
+
result = runner.invoke(cli_main, ["image", "push", "myimage:latest"])
|
30
|
+
|
31
|
+
assert result.exit_code == 1
|
32
|
+
assert "Authentication failed" in result.output
|
33
|
+
assert "VELLUM_API_KEY" in result.output
|
34
|
+
|
35
|
+
|
36
|
+
@patch("subprocess.run")
|
37
|
+
@patch("docker.from_env")
|
38
|
+
def test_image_push_docker_service_token_500_error(mock_docker_from_env, mock_run, vellum_client, monkeypatch):
|
39
|
+
monkeypatch.setenv("VELLUM_API_URL", "https://api.vellum.ai")
|
40
|
+
monkeypatch.setenv("VELLUM_API_KEY", "123456abcdef")
|
41
|
+
|
42
|
+
mock_docker_client = mock_docker_from_env.return_value
|
43
|
+
mock_docker_client.images.get.return_value.id = "test-image-id"
|
44
|
+
|
45
|
+
mock_run.side_effect = [
|
46
|
+
subprocess.CompletedProcess(
|
47
|
+
args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
|
48
|
+
),
|
49
|
+
]
|
50
|
+
|
51
|
+
vellum_client.container_images.docker_service_token.side_effect = ApiError(
|
52
|
+
status_code=500, body="Internal Server Error"
|
53
|
+
)
|
54
|
+
|
55
|
+
runner = CliRunner()
|
56
|
+
result = runner.invoke(cli_main, ["image", "push", "myimage:latest"])
|
57
|
+
|
58
|
+
assert result.exit_code == 1
|
59
|
+
assert "Server error" in result.output
|
60
|
+
assert "try again later" in result.output
|
61
|
+
|
62
|
+
|
63
|
+
@patch("subprocess.run")
|
64
|
+
@patch("docker.from_env")
|
65
|
+
def test_image_push_docker_service_token_other_error(mock_docker_from_env, mock_run, vellum_client, monkeypatch):
|
66
|
+
monkeypatch.setenv("VELLUM_API_URL", "https://api.vellum.ai")
|
67
|
+
monkeypatch.setenv("VELLUM_API_KEY", "123456abcdef")
|
68
|
+
|
69
|
+
mock_docker_client = mock_docker_from_env.return_value
|
70
|
+
mock_docker_client.images.get.return_value.id = "test-image-id"
|
71
|
+
|
72
|
+
mock_run.side_effect = [
|
73
|
+
subprocess.CompletedProcess(
|
74
|
+
args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
|
75
|
+
),
|
76
|
+
]
|
77
|
+
|
78
|
+
vellum_client.container_images.docker_service_token.side_effect = ApiError(
|
79
|
+
status_code=429, body="Too Many Requests"
|
80
|
+
)
|
81
|
+
|
82
|
+
runner = CliRunner()
|
83
|
+
result = runner.invoke(cli_main, ["image", "push", "myimage:latest"])
|
84
|
+
|
85
|
+
assert result.exit_code == 1
|
86
|
+
assert "API request failed" in result.output
|
87
|
+
assert "HTTP 429" in result.output
|
88
|
+
|
89
|
+
|
90
|
+
@patch("subprocess.run")
|
91
|
+
@patch("docker.from_env")
|
92
|
+
def test_image_push_container_image_401_error(mock_docker_from_env, mock_run, vellum_client, monkeypatch):
|
93
|
+
monkeypatch.setenv("VELLUM_API_URL", "https://api.vellum.ai")
|
94
|
+
monkeypatch.setenv("VELLUM_API_KEY", "123456abcdef")
|
95
|
+
|
96
|
+
mock_docker_client = mock_docker_from_env.return_value
|
97
|
+
mock_docker_client.images.get.return_value.id = "test-image-id"
|
98
|
+
mock_docker_client.images.push.return_value = ["pushed"]
|
99
|
+
|
100
|
+
mock_run.side_effect = [
|
101
|
+
subprocess.CompletedProcess(
|
102
|
+
args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
|
103
|
+
),
|
104
|
+
subprocess.CompletedProcess(args="", returncode=0, stdout=b'[{"RepoDigests": ["test-repo@sha256:abcd1234"]}]'),
|
105
|
+
]
|
106
|
+
|
107
|
+
vellum_client.container_images.docker_service_token.return_value = type(
|
108
|
+
"obj", (object,), {"access_token": "345678mnopqr", "organization_id": str(uuid4()), "repository": "myrepo.net"}
|
109
|
+
)()
|
110
|
+
|
111
|
+
vellum_client.container_images.push_container_image.side_effect = ApiError(status_code=401, body="Unauthorized")
|
112
|
+
|
113
|
+
runner = CliRunner()
|
114
|
+
result = runner.invoke(cli_main, ["image", "push", "myimage:latest"])
|
115
|
+
|
116
|
+
assert result.exit_code == 1
|
117
|
+
assert "Authentication failed" in result.output
|
118
|
+
assert "VELLUM_API_KEY" in result.output
|
119
|
+
|
120
|
+
|
121
|
+
@patch("subprocess.run")
|
122
|
+
@patch("docker.from_env")
|
123
|
+
def test_image_push_container_image_500_error(mock_docker_from_env, mock_run, vellum_client, monkeypatch):
|
124
|
+
monkeypatch.setenv("VELLUM_API_URL", "https://api.vellum.ai")
|
125
|
+
monkeypatch.setenv("VELLUM_API_KEY", "123456abcdef")
|
126
|
+
|
127
|
+
mock_docker_client = mock_docker_from_env.return_value
|
128
|
+
mock_docker_client.images.get.return_value.id = "test-image-id"
|
129
|
+
mock_docker_client.images.push.return_value = ["pushed"]
|
130
|
+
|
131
|
+
mock_run.side_effect = [
|
132
|
+
subprocess.CompletedProcess(
|
133
|
+
args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
|
134
|
+
),
|
135
|
+
subprocess.CompletedProcess(args="", returncode=0, stdout=b'[{"RepoDigests": ["test-repo@sha256:abcd1234"]}]'),
|
136
|
+
]
|
137
|
+
|
138
|
+
vellum_client.container_images.docker_service_token.return_value = type(
|
139
|
+
"obj", (object,), {"access_token": "345678mnopqr", "organization_id": str(uuid4()), "repository": "myrepo.net"}
|
140
|
+
)()
|
141
|
+
|
142
|
+
vellum_client.container_images.push_container_image.side_effect = ApiError(
|
143
|
+
status_code=500, body="Internal Server Error"
|
144
|
+
)
|
145
|
+
|
146
|
+
runner = CliRunner()
|
147
|
+
result = runner.invoke(cli_main, ["image", "push", "myimage:latest"])
|
148
|
+
|
149
|
+
assert result.exit_code == 1
|
150
|
+
assert "Server error" in result.output
|
151
|
+
assert "try again later" in result.output
|
152
|
+
|
153
|
+
|
154
|
+
@patch("subprocess.run")
|
155
|
+
@patch("docker.from_env")
|
156
|
+
def test_image_push_container_image_other_error(mock_docker_from_env, mock_run, vellum_client, monkeypatch):
|
157
|
+
monkeypatch.setenv("VELLUM_API_URL", "https://api.vellum.ai")
|
158
|
+
monkeypatch.setenv("VELLUM_API_KEY", "123456abcdef")
|
159
|
+
|
160
|
+
mock_docker_client = mock_docker_from_env.return_value
|
161
|
+
mock_docker_client.images.get.return_value.id = "test-image-id"
|
162
|
+
mock_docker_client.images.push.return_value = ["pushed"]
|
163
|
+
|
164
|
+
mock_run.side_effect = [
|
165
|
+
subprocess.CompletedProcess(
|
166
|
+
args="", returncode=0, stdout=b'{"manifests": [{"platform": {"architecture": "amd64"}}]}'
|
167
|
+
),
|
168
|
+
subprocess.CompletedProcess(args="", returncode=0, stdout=b'[{"RepoDigests": ["test-repo@sha256:abcd1234"]}]'),
|
169
|
+
]
|
170
|
+
|
171
|
+
vellum_client.container_images.docker_service_token.return_value = type(
|
172
|
+
"obj", (object,), {"access_token": "345678mnopqr", "organization_id": str(uuid4()), "repository": "myrepo.net"}
|
173
|
+
)()
|
174
|
+
|
175
|
+
vellum_client.container_images.push_container_image.side_effect = ApiError(
|
176
|
+
status_code=429, body="Too Many Requests"
|
177
|
+
)
|
178
|
+
|
179
|
+
runner = CliRunner()
|
180
|
+
result = runner.invoke(cli_main, ["image", "push", "myimage:latest"])
|
181
|
+
|
182
|
+
assert result.exit_code == 1
|
183
|
+
assert "API request failed" in result.output
|
184
|
+
assert "HTTP 429" in result.output
|
vellum_cli/tests/test_pull.py
CHANGED
@@ -745,7 +745,7 @@ def test_pull__same_pull_twice__one_entry_in_lockfile(vellum_client, mock_module
|
|
745
745
|
zip_contents = _zip_file_map({"workflow.py": "print('hello')"})
|
746
746
|
responses = iter([zip_contents, zip_contents])
|
747
747
|
|
748
|
-
def workflows_pull_side_effect(*
|
748
|
+
def workflows_pull_side_effect(*_args, **_kwargs):
|
749
749
|
return iter([next(responses)])
|
750
750
|
|
751
751
|
vellum_client.workflows.pull.side_effect = workflows_pull_side_effect
|
@@ -890,6 +890,7 @@ def test_pull__module_name_from_deployment_name(vellum_client):
|
|
890
890
|
assert f.read() == "print('hello')"
|
891
891
|
|
892
892
|
|
893
|
+
@pytest.mark.usefixtures("mock_module")
|
893
894
|
def test_pull__invalid_zip_file(vellum_client):
|
894
895
|
workflow_deployment = "test-workflow-deployment-id"
|
895
896
|
|
@@ -903,11 +904,12 @@ def test_pull__invalid_zip_file(vellum_client):
|
|
903
904
|
# THEN the command returns an error
|
904
905
|
assert result.exit_code == 1
|
905
906
|
assert (
|
906
|
-
|
907
|
-
|
907
|
+
"Invalid response format" in result.output
|
908
|
+
or "Please verify your `VELLUM_API_URL` environment variable is set correctly" in result.output
|
908
909
|
)
|
909
910
|
|
910
911
|
|
912
|
+
@pytest.mark.usefixtures("mock_module")
|
911
913
|
def test_pull__json_decode_error(vellum_client):
|
912
914
|
workflow_deployment = "test-workflow-deployment-id"
|
913
915
|
|
@@ -927,11 +929,12 @@ def test_pull__json_decode_error(vellum_client):
|
|
927
929
|
# THEN the command returns an error
|
928
930
|
assert result.exit_code == 1
|
929
931
|
assert (
|
930
|
-
|
931
|
-
|
932
|
+
"API request failed" in result.output
|
933
|
+
or "Please verify your `VELLUM_API_URL` environment variable is set correctly" in result.output
|
932
934
|
)
|
933
935
|
|
934
936
|
|
937
|
+
@pytest.mark.usefixtures("mock_module")
|
935
938
|
def test_pull__unauthorized_error_path(vellum_client):
|
936
939
|
workflow_deployment = "test-workflow-deployment-id"
|
937
940
|
|
@@ -948,9 +951,10 @@ def test_pull__unauthorized_error_path(vellum_client):
|
|
948
951
|
|
949
952
|
# THEN the command returns an error
|
950
953
|
assert result.exit_code == 1
|
951
|
-
assert
|
954
|
+
assert "Please make sure your `VELLUM_API_KEY` environment variable is set correctly" in result.output
|
952
955
|
|
953
956
|
|
957
|
+
@pytest.mark.usefixtures("mock_module")
|
954
958
|
def test_pull__unexpected_error_path(vellum_client):
|
955
959
|
workflow_deployment = "test-workflow-deployment-id"
|
956
960
|
|
@@ -968,9 +972,8 @@ def test_pull__unexpected_error_path(vellum_client):
|
|
968
972
|
# THEN the command returns an error
|
969
973
|
assert result.exit_code == 1
|
970
974
|
assert (
|
971
|
-
|
972
|
-
|
973
|
-
Please try again later and contact support if the problem persists."""
|
975
|
+
"Server error occurred" in result.output
|
976
|
+
or "Please try again in a few moments. If the problem persists, contact Vellum support" in result.output
|
974
977
|
)
|
975
978
|
|
976
979
|
|