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.
Files changed (33) hide show
  1. vellum/client/README.md +1 -1
  2. vellum/client/core/client_wrapper.py +1 -1
  3. vellum/client/reference.md +2767 -0
  4. vellum/client/types/document_read.py +0 -1
  5. vellum/client/types/folder_entity_prompt_sandbox_data.py +1 -0
  6. vellum/client/types/folder_entity_workflow_sandbox_data.py +1 -0
  7. vellum/workflows/expressions/accessor.py +22 -5
  8. vellum/workflows/expressions/tests/test_accessor.py +189 -0
  9. vellum/workflows/nodes/bases/base.py +30 -39
  10. vellum/workflows/nodes/bases/tests/test_base_node.py +48 -2
  11. vellum/workflows/nodes/displayable/api_node/node.py +3 -1
  12. vellum/workflows/nodes/displayable/api_node/tests/test_api_node.py +32 -0
  13. vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +28 -0
  14. vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py +26 -23
  15. vellum/workflows/nodes/displayable/conditional_node/node.py +1 -2
  16. vellum/workflows/nodes/displayable/final_output_node/node.py +2 -0
  17. vellum/workflows/nodes/displayable/inline_prompt_node/node.py +4 -14
  18. vellum/workflows/nodes/displayable/search_node/node.py +8 -0
  19. vellum/workflows/nodes/displayable/search_node/tests/test_node.py +19 -0
  20. vellum/workflows/nodes/experimental/tool_calling_node/utils.py +4 -13
  21. vellum/workflows/runner/runner.py +13 -17
  22. vellum/workflows/state/base.py +0 -4
  23. {vellum_ai-0.14.65.dist-info → vellum_ai-0.14.67.dist-info}/METADATA +2 -2
  24. {vellum_ai-0.14.65.dist-info → vellum_ai-0.14.67.dist-info}/RECORD +33 -30
  25. vellum_cli/image_push.py +62 -7
  26. vellum_cli/pull.py +38 -9
  27. vellum_cli/tests/test_image_push_error_handling.py +184 -0
  28. vellum_cli/tests/test_pull.py +12 -9
  29. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py +661 -0
  30. vellum_ee/workflows/display/utils/expressions.py +17 -0
  31. {vellum_ai-0.14.65.dist-info → vellum_ai-0.14.67.dist-info}/LICENSE +0 -0
  32. {vellum_ai-0.14.65.dist-info → vellum_ai-0.14.67.dist-info}/WHEEL +0 -0
  33. {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
@@ -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(*args, **kwargs):
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
- str(result.exception)
907
- == "The API we tried to pull from returned an invalid zip file. Please make sure your `VELLUM_API_URL` environment variable is set correctly." # noqa: E501
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
- str(result.exception)
931
- == "The API we tried to pull is invalid. Please make sure your `VELLUM_API_URL` environment variable is set correctly." # noqa: E501
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 str(result.exception) == "Please make sure your `VELLUM_API_KEY` environment variable is set correctly."
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
- str(result.exception)
972
- == """The Pull API failed with an unexpected error. \
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