vellum-ai 0.14.64__py3-none-any.whl → 0.14.66__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.
@@ -32,7 +32,6 @@ class DocumentRead(UniversalBaseModel):
32
32
  """
33
33
 
34
34
  original_file_url: typing.Optional[str] = None
35
- processed_file_url: typing.Optional[str] = None
36
35
  document_to_document_indexes: typing.List[DocumentDocumentToDocumentIndex]
37
36
  metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None)
38
37
  """
@@ -14,6 +14,7 @@ class FolderEntityPromptSandboxData(UniversalBaseModel):
14
14
  created: dt.datetime
15
15
  modified: dt.datetime
16
16
  status: EntityStatus
17
+ description: typing.Optional[str] = None
17
18
  last_deployed_on: typing.Optional[dt.datetime] = None
18
19
 
19
20
  if IS_PYDANTIC_V2:
@@ -14,6 +14,7 @@ class FolderEntityWorkflowSandboxData(UniversalBaseModel):
14
14
  created: dt.datetime
15
15
  modified: dt.datetime
16
16
  status: EntityStatus
17
+ description: typing.Optional[str] = None
17
18
  last_deployed_on: typing.Optional[dt.datetime] = None
18
19
 
19
20
  if IS_PYDANTIC_V2:
@@ -35,20 +35,37 @@ class AccessorExpression(BaseDescriptor[Any]):
35
35
  if isinstance(self._field, int):
36
36
  raise InvalidExpressionException("Cannot access field by index on a dataclass")
37
37
 
38
- return getattr(base, self._field)
38
+ try:
39
+ return getattr(base, self._field)
40
+ except AttributeError:
41
+ raise InvalidExpressionException(f"Field '{self._field}' not found on dataclass {type(base).__name__}")
39
42
 
40
43
  if isinstance(base, BaseModel):
41
44
  if isinstance(self._field, int):
42
45
  raise InvalidExpressionException("Cannot access field by index on a BaseModel")
43
46
 
44
- return getattr(base, self._field)
47
+ try:
48
+ return getattr(base, self._field)
49
+ except AttributeError:
50
+ raise InvalidExpressionException(f"Field '{self._field}' not found on BaseModel {type(base).__name__}")
45
51
 
46
52
  if isinstance(base, Mapping):
47
- return base[self._field]
53
+ try:
54
+ return base[self._field]
55
+ except KeyError:
56
+ raise InvalidExpressionException(f"Key '{self._field}' not found in mapping")
48
57
 
49
58
  if isinstance(base, Sequence):
50
- index = int(self._field)
51
- return base[index]
59
+ try:
60
+ index = int(self._field)
61
+ return base[index]
62
+ except (IndexError, ValueError):
63
+ if isinstance(self._field, int) or (isinstance(self._field, str) and self._field.lstrip("-").isdigit()):
64
+ raise InvalidExpressionException(
65
+ f"Index {self._field} is out of bounds for sequence of length {len(base)}"
66
+ )
67
+ else:
68
+ raise InvalidExpressionException(f"Invalid index '{self._field}' for sequence access")
52
69
 
53
70
  raise InvalidExpressionException(f"Cannot get field {self._field} from {base}")
54
71
 
@@ -0,0 +1,189 @@
1
+ import pytest
2
+ from dataclasses import dataclass
3
+
4
+ from pydantic import BaseModel
5
+
6
+ from vellum.workflows.descriptors.exceptions import InvalidExpressionException
7
+ from vellum.workflows.expressions.accessor import AccessorExpression
8
+ from vellum.workflows.references.constant import ConstantValueReference
9
+ from vellum.workflows.state.base import BaseState
10
+
11
+
12
+ @dataclass
13
+ class TestDataclass:
14
+ name: str
15
+ value: int
16
+
17
+
18
+ class TestBaseModel(BaseModel):
19
+ name: str
20
+ value: int
21
+
22
+
23
+ class TestState(BaseState):
24
+ pass
25
+
26
+
27
+ def test_accessor_expression_dict_valid_key():
28
+ state = TestState()
29
+ base_ref = ConstantValueReference({"name": "test", "value": 42})
30
+ accessor = AccessorExpression(base=base_ref, field="name")
31
+
32
+ result = accessor.resolve(state)
33
+
34
+ assert result == "test"
35
+
36
+
37
+ def test_accessor_expression_dict_invalid_key():
38
+ state = TestState()
39
+ base_ref = ConstantValueReference({"name": "test", "value": 42})
40
+ accessor = AccessorExpression(base=base_ref, field="missing_key")
41
+
42
+ with pytest.raises(InvalidExpressionException) as exc_info:
43
+ accessor.resolve(state)
44
+
45
+ assert "Key 'missing_key' not found in mapping" in str(exc_info.value)
46
+
47
+
48
+ def test_accessor_expression_list_valid_index():
49
+ state = TestState()
50
+ base_ref = ConstantValueReference(["first", "second", "third"])
51
+ accessor = AccessorExpression(base=base_ref, field=1)
52
+
53
+ result = accessor.resolve(state)
54
+
55
+ assert result == "second"
56
+
57
+
58
+ def test_accessor_expression_list_invalid_index():
59
+ state = TestState()
60
+ base_ref = ConstantValueReference(["first", "second"])
61
+ accessor = AccessorExpression(base=base_ref, field=5)
62
+
63
+ with pytest.raises(InvalidExpressionException) as exc_info:
64
+ accessor.resolve(state)
65
+
66
+ assert "Index 5 is out of bounds for sequence of length 2" in str(exc_info.value)
67
+
68
+
69
+ def test_accessor_expression_list_negative_index():
70
+ state = TestState()
71
+ base_ref = ConstantValueReference(["first", "second", "third"])
72
+ accessor = AccessorExpression(base=base_ref, field=-1)
73
+
74
+ result = accessor.resolve(state)
75
+
76
+ assert result == "third"
77
+
78
+
79
+ def test_accessor_expression_list_invalid_negative_index():
80
+ state = TestState()
81
+ base_ref = ConstantValueReference(["first", "second"])
82
+ accessor = AccessorExpression(base=base_ref, field=-5)
83
+
84
+ with pytest.raises(InvalidExpressionException) as exc_info:
85
+ accessor.resolve(state)
86
+
87
+ assert "Index -5 is out of bounds for sequence of length 2" in str(exc_info.value)
88
+
89
+
90
+ def test_accessor_expression_list_string_index():
91
+ state = TestState()
92
+ base_ref = ConstantValueReference(["first", "second", "third"])
93
+ accessor = AccessorExpression(base=base_ref, field="1")
94
+
95
+ result = accessor.resolve(state)
96
+
97
+ assert result == "second"
98
+
99
+
100
+ def test_accessor_expression_list_invalid_string_index():
101
+ state = TestState()
102
+ base_ref = ConstantValueReference(["first", "second"])
103
+ accessor = AccessorExpression(base=base_ref, field="invalid")
104
+
105
+ with pytest.raises(InvalidExpressionException) as exc_info:
106
+ accessor.resolve(state)
107
+
108
+ assert "Invalid index 'invalid' for sequence access" in str(exc_info.value)
109
+
110
+
111
+ def test_accessor_expression_dataclass_valid_field():
112
+ state = TestState()
113
+ test_obj = TestDataclass(name="test", value=42)
114
+ base_ref = ConstantValueReference(test_obj)
115
+ accessor = AccessorExpression(base=base_ref, field="name")
116
+
117
+ result = accessor.resolve(state)
118
+
119
+ assert result == "test"
120
+
121
+
122
+ def test_accessor_expression_dataclass_invalid_field():
123
+ state = TestState()
124
+ test_obj = TestDataclass(name="test", value=42)
125
+ base_ref = ConstantValueReference(test_obj)
126
+ accessor = AccessorExpression(base=base_ref, field="missing_field")
127
+
128
+ with pytest.raises(InvalidExpressionException) as exc_info:
129
+ accessor.resolve(state)
130
+
131
+ assert "Field 'missing_field' not found on dataclass TestDataclass" in str(exc_info.value)
132
+
133
+
134
+ def test_accessor_expression_basemodel_valid_field():
135
+ state = TestState()
136
+ test_obj = TestBaseModel(name="test", value=42)
137
+ base_ref = ConstantValueReference(test_obj)
138
+ accessor = AccessorExpression(base=base_ref, field="name")
139
+
140
+ result = accessor.resolve(state)
141
+
142
+ assert result == "test"
143
+
144
+
145
+ def test_accessor_expression_basemodel_invalid_field():
146
+ state = TestState()
147
+ test_obj = TestBaseModel(name="test", value=42)
148
+ base_ref = ConstantValueReference(test_obj)
149
+ accessor = AccessorExpression(base=base_ref, field="missing_field")
150
+
151
+ with pytest.raises(InvalidExpressionException) as exc_info:
152
+ accessor.resolve(state)
153
+
154
+ assert "Field 'missing_field' not found on BaseModel TestBaseModel" in str(exc_info.value)
155
+
156
+
157
+ def test_accessor_expression_dataclass_index_access():
158
+ state = TestState()
159
+ test_obj = TestDataclass(name="test", value=42)
160
+ base_ref = ConstantValueReference(test_obj)
161
+ accessor = AccessorExpression(base=base_ref, field=0)
162
+
163
+ with pytest.raises(InvalidExpressionException) as exc_info:
164
+ accessor.resolve(state)
165
+
166
+ assert "Cannot access field by index on a dataclass" in str(exc_info.value)
167
+
168
+
169
+ def test_accessor_expression_basemodel_index_access():
170
+ state = TestState()
171
+ test_obj = TestBaseModel(name="test", value=42)
172
+ base_ref = ConstantValueReference(test_obj)
173
+ accessor = AccessorExpression(base=base_ref, field=0)
174
+
175
+ with pytest.raises(InvalidExpressionException) as exc_info:
176
+ accessor.resolve(state)
177
+
178
+ assert "Cannot access field by index on a BaseModel" in str(exc_info.value)
179
+
180
+
181
+ def test_accessor_expression_unsupported_type():
182
+ state = TestState()
183
+ base_ref = ConstantValueReference(42)
184
+ accessor = AccessorExpression(base=base_ref, field="field")
185
+
186
+ with pytest.raises(InvalidExpressionException) as exc_info:
187
+ accessor.resolve(state)
188
+
189
+ assert "Cannot get field field from 42" in str(exc_info.value)
@@ -192,7 +192,30 @@ def test_validation_with_extra_variables(vellum_adhoc_prompt_client):
192
192
  ]
193
193
 
194
194
 
195
- def test_inline_prompt_node__json_output(vellum_adhoc_prompt_client):
195
+ @pytest.mark.parametrize(
196
+ "custom_parameters,test_description",
197
+ [
198
+ (
199
+ {
200
+ "json_mode": False,
201
+ "json_schema": {
202
+ "name": "get_result",
203
+ "schema": {
204
+ "type": "object",
205
+ "required": ["result"],
206
+ "properties": {"result": {"type": "string", "description": ""}},
207
+ },
208
+ },
209
+ },
210
+ "with json_schema configured",
211
+ ),
212
+ (
213
+ {},
214
+ "without json_mode or json_schema configured",
215
+ ),
216
+ ],
217
+ )
218
+ def test_inline_prompt_node__json_output(vellum_adhoc_prompt_client, custom_parameters, test_description):
196
219
  """Confirm that InlinePromptNodes output the expected JSON when run."""
197
220
 
198
221
  # GIVEN a node that subclasses InlinePromptNode
@@ -214,17 +237,7 @@ def test_inline_prompt_node__json_output(vellum_adhoc_prompt_client):
214
237
  frequency_penalty=0.0,
215
238
  presence_penalty=0.0,
216
239
  logit_bias=None,
217
- custom_parameters={
218
- "json_mode": False,
219
- "json_schema": {
220
- "name": "get_result",
221
- "schema": {
222
- "type": "object",
223
- "required": ["result"],
224
- "properties": {"result": {"type": "string", "description": ""}},
225
- },
226
- },
227
- },
240
+ custom_parameters=custom_parameters,
228
241
  )
229
242
 
230
243
  # AND a known JSON response from invoking an inline prompt
@@ -284,17 +297,7 @@ def test_inline_prompt_node__json_output(vellum_adhoc_prompt_client):
284
297
  frequency_penalty=0.0,
285
298
  presence_penalty=0.0,
286
299
  logit_bias=None,
287
- custom_parameters={
288
- "json_mode": False,
289
- "json_schema": {
290
- "name": "get_result",
291
- "schema": {
292
- "type": "object",
293
- "required": ["result"],
294
- "properties": {"result": {"type": "string", "description": ""}},
295
- },
296
- },
297
- },
300
+ custom_parameters=custom_parameters,
298
301
  ),
299
302
  request_options=mock.ANY,
300
303
  settings=None,
@@ -48,26 +48,16 @@ class InlinePromptNode(BaseInlinePromptNode[StateType]):
48
48
  string_outputs = []
49
49
  json_output = None
50
50
 
51
- should_parse_json = False
52
- if hasattr(self, "parameters"):
53
- custom_params = self.parameters.custom_parameters
54
- if custom_params and isinstance(custom_params, dict):
55
- json_schema = custom_params.get("json_schema", {})
56
- if (isinstance(json_schema, dict) and "schema" in json_schema) or custom_params.get("json_mode", {}):
57
- should_parse_json = True
58
-
59
51
  for output in outputs:
60
52
  if output.value is None:
61
53
  continue
62
54
 
63
55
  if output.type == "STRING":
64
56
  string_outputs.append(output.value)
65
- if should_parse_json:
66
- try:
67
- parsed_json = json.loads(output.value)
68
- json_output = parsed_json
69
- except (json.JSONDecodeError, TypeError):
70
- pass
57
+ try:
58
+ json_output = json.loads(output.value)
59
+ except (json.JSONDecodeError, TypeError):
60
+ pass
71
61
  elif output.type == "JSON":
72
62
  string_outputs.append(json.dumps(output.value, indent=4))
73
63
  json_output = output.value
@@ -15,7 +15,6 @@ from vellum.client.types.string_chat_message_content import StringChatMessageCon
15
15
  from vellum.client.types.variable_prompt_block import VariablePromptBlock
16
16
  from vellum.workflows.errors.types import WorkflowErrorCode
17
17
  from vellum.workflows.exceptions import NodeException
18
- from vellum.workflows.inputs.base import BaseInputs
19
18
  from vellum.workflows.nodes.bases import BaseNode
20
19
  from vellum.workflows.nodes.displayable.code_execution_node.node import CodeExecutionNode
21
20
  from vellum.workflows.nodes.displayable.inline_prompt_node.node import InlinePromptNode
@@ -143,24 +142,16 @@ def create_function_node(
143
142
  packages: Optional list of packages to install for code execution (only used for regular functions)
144
143
  runtime: The runtime to use for code execution (default: "PYTHON_3_11_6")
145
144
  """
146
-
147
145
  if is_workflow_class(function):
148
-
146
+ # Create a class-level wrapper that calls the original function
149
147
  def execute_function(self) -> BaseNode.Outputs:
150
148
  outputs = self.state.meta.node_outputs.get(tool_router_node.Outputs.text)
151
- # first parse into json
149
+
152
150
  outputs = json.loads(outputs)
153
151
  arguments = outputs["arguments"]
154
152
 
155
- # Dynamically define an Inputs subclass of BaseInputs
156
- Inputs = type(
157
- "Inputs",
158
- (BaseInputs,),
159
- {"__annotations__": {k: type(v) for k, v in arguments.items()}},
160
- )
161
-
162
- # Create an instance with arguments
163
- inputs_instance = Inputs(**arguments)
153
+ # Call the function based on its type
154
+ inputs_instance = function.get_inputs_class()(**arguments)
164
155
 
165
156
  workflow = function()
166
157
  terminal_event = workflow.run(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.14.64
3
+ Version: 0.14.66
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -21,7 +21,7 @@ Classifier: Programming Language :: Python :: 3.8
21
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
22
  Classifier: Typing :: Typed
23
23
  Requires-Dist: Jinja2 (>=3.1.0,<4.0.0)
24
- Requires-Dist: click (>=8.1.0,<9.0.0)
24
+ Requires-Dist: click (>=8.1.7,<9.0.0)
25
25
  Requires-Dist: docker (>=7.1.0,<8.0.0)
26
26
  Requires-Dist: httpx (>=0.21.2)
27
27
  Requires-Dist: openai (>=1.0.0,<2.0.0)
@@ -30,6 +30,7 @@ Requires-Dist: publication (==0.0.3)
30
30
  Requires-Dist: pydantic (>=1.9.2)
31
31
  Requires-Dist: pydantic-core (>=2.18.2,<3.0.0)
32
32
  Requires-Dist: pydash (>=7.0.0,<8.0.0)
33
+ Requires-Dist: python-dateutil (>=2.8.0,<3.0.0)
33
34
  Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
34
35
  Requires-Dist: pytz (>=2022.0,<2026.0)
35
36
  Requires-Dist: pyyaml (>=6.0.0,<7.0.0)
@@ -3,20 +3,21 @@ vellum_cli/README.md,sha256=2NudRoLzWxNKqnuVy1JuQ7DerIaxWGYkrH8kMd-asIE,90
3
3
  vellum_cli/__init__.py,sha256=2_6oGoVcLFUh4L63Kz4SBL4Y6XevJ70oYbg7BJ3cb5Q,12569
4
4
  vellum_cli/aliased_group.py,sha256=ugW498j0yv4ALJ8vS9MsO7ctDW7Jlir9j6nE_uHAP8c,3363
5
5
  vellum_cli/config.py,sha256=v5BmZ-t_v4Jmqd7KVuQMZF2pRI-rbMspSkVYXIRoTmI,9448
6
- vellum_cli/image_push.py,sha256=skFXf25ixMOX1yfcyAtii-RivYYv-_hsv-Z-bVB6m5Q,7380
6
+ vellum_cli/image_push.py,sha256=mjK3Fj3_MIhIGmurYVz_OC-hCoAef5LqDb0OppKJIJc,9909
7
7
  vellum_cli/init.py,sha256=WpnMXPItPmh0f0bBGIer3p-e5gu8DUGwSArT_FuoMEw,5093
8
8
  vellum_cli/logger.py,sha256=dcM_OmgqXLo93vDYswO5ylyUQQcTfnA5GTd5tbIt3wM,1446
9
9
  vellum_cli/ping.py,sha256=p_BCCRjgPhng6JktuECtkDQLbhopt6JpmrtGoLnLJT8,1161
10
- vellum_cli/pull.py,sha256=M50yXzA_35N35gk1Y8KjLbXrzdRG86--XFQvEukxGtA,13371
10
+ vellum_cli/pull.py,sha256=udYyPlJ6VKDdh78rApNJOZgxHl82fcV6iGnRPSdX1LY,14750
11
11
  vellum_cli/push.py,sha256=wxRlFu2mYW9SvwODYxwajri1mDQ2be0n-9i0d9QAc30,10194
12
12
  vellum_cli/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  vellum_cli/tests/conftest.py,sha256=AFYZryKA2qnUuCPBxBKmHLFoPiE0WhBFFej9tNwSHdc,1526
14
14
  vellum_cli/tests/test_config.py,sha256=uvKGDc8BoVyT9_H0Z-g8469zVxomn6Oi3Zj-vK7O_wU,2631
15
15
  vellum_cli/tests/test_image_push.py,sha256=QM-JlR_aJappvwbCLteQZZf76sd7SE1sRj3armvFK-I,5706
16
+ vellum_cli/tests/test_image_push_error_handling.py,sha256=_Wjfkn1orI2K4Ahzqz4u8T13or7NOX01K4BtcTuTIOM,7107
16
17
  vellum_cli/tests/test_init.py,sha256=8UOc_ThfouR4ja5cCl_URuLk7ohr9JXfCnG4yka1OUQ,18754
17
18
  vellum_cli/tests/test_main.py,sha256=qDZG-aQauPwBwM6A2DIu1494n47v3pL28XakTbLGZ-k,272
18
19
  vellum_cli/tests/test_ping.py,sha256=3ucVRThEmTadlV9LrJdCCrr1Ofj3rOjG6ue0BNR2UC0,2523
19
- vellum_cli/tests/test_pull.py,sha256=7HRAhIdkVW5mR2VckEaNDjp4rt-MlIxOWMMI2XNUPE8,49814
20
+ vellum_cli/tests/test_pull.py,sha256=91aOAYNzYcJuIrTwRvGX_Qa1_UOmdCfVAfvZVfwCKZ4,49902
20
21
  vellum_cli/tests/test_push.py,sha256=I8XICg3pUb3yxAFLXziVHHf5CRm354LO-uUfwtca3bU,33897
21
22
  vellum_ee/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
23
  vellum_ee/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -130,11 +131,11 @@ vellum_ee/workflows/tests/test_display_meta.py,sha256=DIzjNbwK1-4mlttPML6NskQ4rP
130
131
  vellum_ee/workflows/tests/test_server.py,sha256=SsOkS6sGO7uGC4mxvk4iv8AtcXs058P9hgFHzTWmpII,14519
131
132
  vellum_ee/workflows/tests/test_virtual_files.py,sha256=TJEcMR0v2S8CkloXNmCHA0QW0K6pYNGaIjraJz7sFvY,2762
132
133
  vellum/__init__.py,sha256=U4MVBzBx8I8-rOG_feluSz5U8_hD969e85F4cRgmVv4,42104
133
- vellum/client/README.md,sha256=qmaVIP42MnxAu8jV7u-CsgVFfs3-pHQODrXdZdFxtaw,4749
134
+ vellum/client/README.md,sha256=CuGUYnaE0Imt0KqQ4sIPaUghCjLHkF3DdEvZWu14-8s,4807
134
135
  vellum/client/__init__.py,sha256=AYopGv2ZRVn3zsU8_km6KOvEHDbXiTPCVuYVI7bWvdA,120166
135
136
  vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
136
137
  vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
137
- vellum/client/core/client_wrapper.py,sha256=EBMKy4AU89W_wlhww7wsWGLScDvYus97WUeayU5Ejd0,1869
138
+ vellum/client/core/client_wrapper.py,sha256=gluL9LJQaydz9m87P7bWACAysxbElOZWqF6JrbjOjDw,1869
138
139
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
139
140
  vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
140
141
  vellum/client/core/http_client.py,sha256=Z77OIxIbL4OAB2IDqjRq_sYa5yNYAWfmdhdCSSvh6Y4,19552
@@ -150,7 +151,7 @@ vellum/client/errors/bad_request_error.py,sha256=_EbO8mWqN9kFZPvIap8qa1lL_EWkRcs
150
151
  vellum/client/errors/forbidden_error.py,sha256=QO1kKlhClAPES6zsEK7g9pglWnxn3KWaOCAawWOg6Aw,263
151
152
  vellum/client/errors/internal_server_error.py,sha256=8USCagXyJJ1MOm9snpcXIUt6eNXvrd_aq7Gfcu1vlOI,268
152
153
  vellum/client/errors/not_found_error.py,sha256=tBVCeBC8n3C811WHRj_n-hs3h8MqwR5gp0vLiobk7W8,262
153
- vellum/client/reference.md,sha256=I-z_aZGJKDQh443ywv92ezeI9w_XsiLh-vHULu8RsDg,91011
154
+ vellum/client/reference.md,sha256=8JwIEywKFcq7r6YmD8fpb4hG8qq9xTZgjLbVkzDoADQ,53008
154
155
  vellum/client/resources/__init__.py,sha256=XgQao4rJxyYu71j64RFIsshz4op9GE8-i-C5GCv-KVE,1555
155
156
  vellum/client/resources/ad_hoc/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
156
157
  vellum/client/resources/ad_hoc/client.py,sha256=rtpiGR6j8CcXSnN6UW_jYwLLdfJ9dwkTm_nta9oRzno,25933
@@ -288,7 +289,7 @@ vellum/client/types/document_index_indexing_config_request.py,sha256=Wt-ys1o_acH
288
289
  vellum/client/types/document_index_read.py,sha256=ePngiRszr65HLl9D0_FUdhAdMe84nRwyM3cKbr8rFpg,1177
289
290
  vellum/client/types/document_processing_state.py,sha256=ISlurj7jQzwHzxPzDZTqeAIgSIIGMBBPgcOSoe04pTU,211
290
291
  vellum/client/types/document_prompt_block.py,sha256=sgFxN48PILFuuF2KUIwks6PbJ3XH6sCE_8ydLEE_doU,1019
291
- vellum/client/types/document_read.py,sha256=6nwEvVvVe-6y2vtPNYB7KtcFoaydH2ow-WhCmCAvMQ8,1713
292
+ vellum/client/types/document_read.py,sha256=U3YcFLF9exeZYAhLErEdAc_vVTtWZ8efXDKmmcabshg,1661
292
293
  vellum/client/types/document_status.py,sha256=GD_TSoFmZUBJnPl-chAmaQFzQ2_TYO3PSqi3-9QfEHE,122
293
294
  vellum/client/types/document_vellum_value.py,sha256=a8WQhyntwy80iN9j8L9F5v6Jmq1L4j0ETJo9c9VGabs,768
294
295
  vellum/client/types/document_vellum_value_request.py,sha256=utpoRMMVhMIsa4S4ZOaOr2lX76BgrOVolPxCwy9-pUw,797
@@ -329,11 +330,11 @@ vellum/client/types/folder_entity_document_index_data.py,sha256=UceusLf7dLYDHq4Z
329
330
  vellum/client/types/folder_entity_folder.py,sha256=1GWfyHdenyAI2GXiouIbnFhPK4ADqZGFh-6fpp_C6-U,792
330
331
  vellum/client/types/folder_entity_folder_data.py,sha256=JLYkhvRY63-ojNY84lfRTaUg25KjslSE-iNAC2NYCTI,674
331
332
  vellum/client/types/folder_entity_prompt_sandbox.py,sha256=7CGVcK5maoqO7CC7sFfi6F5X0QWdHVbEygqLyci_VDY,839
332
- vellum/client/types/folder_entity_prompt_sandbox_data.py,sha256=4u-t-p2-h7Z1SacNOQnEnY3tt-au5WB0hIDrB1HOeKk,781
333
+ vellum/client/types/folder_entity_prompt_sandbox_data.py,sha256=LMTtOshCdp0MpYHdKtrtBSdpXw9B9id5BfIpkg9SsY4,826
333
334
  vellum/client/types/folder_entity_test_suite.py,sha256=M5sb7ntUX2VsCyD0AYnz7dalt7G1ejOYQZvsUU33q2w,811
334
335
  vellum/client/types/folder_entity_test_suite_data.py,sha256=RGITy3Pip6NeIb77YGavDWgRr8GLFDB9sXrTU_Dm2OI,719
335
336
  vellum/client/types/folder_entity_workflow_sandbox.py,sha256=gFmkwKZGh5O9-9y4w6VGK1IRsKLf7NZ4SCC-pgucm8M,853
336
- vellum/client/types/folder_entity_workflow_sandbox_data.py,sha256=MW0nLAvetgnsm6KWiGcYcKB9llR-UfosSNz0MtokN38,783
337
+ vellum/client/types/folder_entity_workflow_sandbox_data.py,sha256=4_kzQSDrFXVJCSF1st73jo0LxKOicn_gE82XAk-QKJI,828
337
338
  vellum/client/types/fulfilled_ad_hoc_execute_prompt_event.py,sha256=19rFjVrzobaaAQhZlP_WGV9f_Rwrz4EPRXbT2aYkaJw,1016
338
339
  vellum/client/types/fulfilled_execute_prompt_event.py,sha256=E-iBwlMWvwQyRfzqPlgtX8KurE3IYsTRd5vWjXtbOmk,994
339
340
  vellum/client/types/fulfilled_execute_prompt_response.py,sha256=nKhDk2ZloCuE0uijX5XOE63_cq8PBo4UWs4hK4e3jUE,1227
@@ -1505,7 +1506,7 @@ vellum/workflows/events/types.py,sha256=LwgFlMRbptJvdPtPO1POUtGtbhGw7BSuvgHxNSgS
1505
1506
  vellum/workflows/events/workflow.py,sha256=i9JSCANjAhf5uc57gYspdII2V2OLItbc0BfT8yB9mF0,7728
1506
1507
  vellum/workflows/exceptions.py,sha256=NiBiR3ggfmPxBVqD-H1SqmjI-7mIn0EStSN1BqApvCM,1213
1507
1508
  vellum/workflows/expressions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1508
- vellum/workflows/expressions/accessor.py,sha256=ItZF7fMLzVTqsdAiaXb5SiDupXmX0X9xbIus1W6hRds,1870
1509
+ vellum/workflows/expressions/accessor.py,sha256=1kY0sYfednQ_u0kh1Df2WTsDREVIOzU7UuZc5jvj5xw,2861
1509
1510
  vellum/workflows/expressions/and_.py,sha256=I7lNqrUM3-m_5hmjjiMhaHhJtKcLj39kEFVWPDOqwfo,916
1510
1511
  vellum/workflows/expressions/begins_with.py,sha256=FnWsQXbENm0ZwkfEP7dR8Qx4_MMrzj6C1yqAV2KaNHw,1123
1511
1512
  vellum/workflows/expressions/between.py,sha256=dVeddT6YA91eOAlE1Utg7C7gnCiYE7WP-dg17yXUeAY,1492
@@ -1535,6 +1536,7 @@ vellum/workflows/expressions/not_in.py,sha256=pFvwkFPsn3WJw61ssFgM2U1dqWEeglfz4F
1535
1536
  vellum/workflows/expressions/or_.py,sha256=s-8YdMSSCDS2yijR38kguwok3iqmDMMgDYKV93b4O4s,914
1536
1537
  vellum/workflows/expressions/parse_json.py,sha256=xsk6j3HF7bU1yF6fwt5P9Ugcyd5D9ZXrdng11FRilUI,1088
1537
1538
  vellum/workflows/expressions/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1539
+ vellum/workflows/expressions/tests/test_accessor.py,sha256=ijmGjS1pipdurAgYGmfV8Gcle4HIJ5lQHVG18xHjNiQ,5839
1538
1540
  vellum/workflows/expressions/tests/test_expressions.py,sha256=3b6k8xs-CItBBw95NygFLUNoNPKxI4VA1GyWbkMtqyI,11623
1539
1541
  vellum/workflows/expressions/tests/test_parse_json.py,sha256=zpB_qE5_EwWQL7ULQUJm0o1PRSfWZdAqZNW6Ah13oJE,1059
1540
1542
  vellum/workflows/graph/__init__.py,sha256=3sHlay5d_-uD7j3QJXiGl0WHFZZ_QScRvgyDhN2GhHY,74
@@ -1589,7 +1591,7 @@ vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py,sha256=H
1589
1591
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/constants.py,sha256=fnjiRWLoRlC4Puo5oQcpZD5Hd-EesxsAo9l5tGAkpZQ,270
1590
1592
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=cD2RzOX9WE6xTKgm09dsEw4xHATZbOjeGyYCSdl8fjU,11785
1591
1593
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1592
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py,sha256=5CNag1_aEFZbCL0nrOC5e1L-t90-4rp2xDwh0h52hVI,21407
1594
+ vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py,sha256=terQtPqLGiKKGtU7zbkM3XkbVddLQI87bBj31M0zaRE,21356
1593
1595
  vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py,sha256=0a40fkkZkFMmZN0CsWf6EP_y1H6x36EGa3WcfVNyOsM,9797
1594
1596
  vellum/workflows/nodes/displayable/bases/search_node.py,sha256=3UtbqY3QO4kzfJHbmUNZGnEEfJmaoiF892u8H6TGjp8,5381
1595
1597
  vellum/workflows/nodes/displayable/bases/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1616,7 +1618,7 @@ vellum/workflows/nodes/displayable/guardrail_node/test_node.py,sha256=SAGv6hSFcB
1616
1618
  vellum/workflows/nodes/displayable/guardrail_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1617
1619
  vellum/workflows/nodes/displayable/guardrail_node/tests/test_node.py,sha256=X2pd6TI8miYxIa7rgvs1pHTEreyWcf77EyR0_Jsa700,2055
1618
1620
  vellum/workflows/nodes/displayable/inline_prompt_node/__init__.py,sha256=gSUOoEZLlrx35-tQhSAd3An8WDwBqyiQh-sIebLU9wU,74
1619
- vellum/workflows/nodes/displayable/inline_prompt_node/node.py,sha256=8RXZqWMzViUjFfbpmcy1gkSsKnEpci8BGwsuPYv4xMQ,3380
1621
+ vellum/workflows/nodes/displayable/inline_prompt_node/node.py,sha256=ST_V1Z3-7lzZ__Ntfm6iry70u9D3GD2a2vxsl2d4Q_c,2843
1620
1622
  vellum/workflows/nodes/displayable/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1621
1623
  vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py,sha256=bBHs90mV5SZ3rJPAL0wx4WWyawUA406LgMPOdvpZC_A,10923
1622
1624
  vellum/workflows/nodes/displayable/merge_node/__init__.py,sha256=J8IC08dSH7P76wKlNuxe1sn7toNGtSQdFirUbtPDEs0,60
@@ -1646,7 +1648,7 @@ vellum/workflows/nodes/experimental/openai_chat_completion_node/node.py,sha256=c
1646
1648
  vellum/workflows/nodes/experimental/tool_calling_node/__init__.py,sha256=S7OzT3I4cyOU5Beoz87nPwCejCMP2FsHBFL8OcVmxJ4,118
1647
1649
  vellum/workflows/nodes/experimental/tool_calling_node/node.py,sha256=FkhaJccpCbx2be_IZ5V2v6Lo-jPJ0WgSC5tveLvAW4A,5774
1648
1650
  vellum/workflows/nodes/experimental/tool_calling_node/tests/test_node.py,sha256=sxG26mOwt4N36RLoPJ-ngginPqC5qFzD_kGj9izdCFI,1833
1649
- vellum/workflows/nodes/experimental/tool_calling_node/utils.py,sha256=DjFn33XuomM-EiojCFzTlOsWMdF_uYyHzNayBok6X-k,10055
1651
+ vellum/workflows/nodes/experimental/tool_calling_node/utils.py,sha256=vB-tdN-44iVrTFvwGLVZW3dv62imIp5fPo0FYCW0l3M,9815
1650
1652
  vellum/workflows/nodes/mocks.py,sha256=a1FjWEIocseMfjzM-i8DNozpUsaW0IONRpZmXBoWlyc,10455
1651
1653
  vellum/workflows/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1652
1654
  vellum/workflows/nodes/tests/test_mocks.py,sha256=mfPvrs75PKcsNsbJLQAN6PDFoVqs9TmQxpdyFKDdO60,7837
@@ -1712,8 +1714,8 @@ vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnad
1712
1714
  vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1713
1715
  vellum/workflows/workflows/tests/test_base_workflow.py,sha256=fROqff6AZpCIzaSwOKSdtYy4XR0UZQ6ejxL3RJOSJVs,20447
1714
1716
  vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
1715
- vellum_ai-0.14.64.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1716
- vellum_ai-0.14.64.dist-info/METADATA,sha256=tewaEjPiWmDj6JmUJmAXJPiXr51sX5Yvpc3rHxjJw0w,5508
1717
- vellum_ai-0.14.64.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1718
- vellum_ai-0.14.64.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1719
- vellum_ai-0.14.64.dist-info/RECORD,,
1717
+ vellum_ai-0.14.66.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1718
+ vellum_ai-0.14.66.dist-info/METADATA,sha256=bkr1Oj0n0HAwEiTLSb4lZEiDQQM_mtpz1uXZ1Lt7VQM,5556
1719
+ vellum_ai-0.14.66.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1720
+ vellum_ai-0.14.66.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1721
+ vellum_ai-0.14.66.dist-info/RECORD,,
vellum_cli/image_push.py CHANGED
@@ -9,9 +9,10 @@ import docker
9
9
  from docker import DockerClient
10
10
  from dotenv import load_dotenv
11
11
 
12
+ from vellum.client.core.api_error import ApiError
12
13
  from vellum.workflows.vellum_client import create_vellum_client, create_vellum_environment
13
14
  from vellum_cli.config import DEFAULT_WORKSPACE_CONFIG, load_vellum_cli_config
14
- from vellum_cli.logger import load_cli_logger
15
+ from vellum_cli.logger import handle_cli_error, load_cli_logger
15
16
 
16
17
  _SUPPORTED_ARCHITECTURE = "amd64"
17
18
 
@@ -82,7 +83,34 @@ def image_push_command(image: str, tags: Optional[List[str]] = None, workspace:
82
83
  exit(1)
83
84
  else:
84
85
  logger.info("Authenticating...")
85
- auth = vellum_client.container_images.docker_service_token()
86
+ try:
87
+ auth = vellum_client.container_images.docker_service_token()
88
+ except ApiError as e:
89
+ if e.status_code == 401 or e.status_code == 403:
90
+ handle_cli_error(
91
+ logger,
92
+ title="Authentication failed",
93
+ message="Unable to authenticate with Vellum API. Please check your API key.",
94
+ suggestion="Make sure your VELLUM_API_KEY environment variable is set correctly.",
95
+ )
96
+ return
97
+ elif e.status_code == 500:
98
+ handle_cli_error(
99
+ logger,
100
+ title="Server error",
101
+ message="The Vellum API failed with an unexpected server error.",
102
+ suggestion="Please try again later and contact support if the problem persists.",
103
+ )
104
+ return
105
+ else:
106
+ handle_cli_error(
107
+ logger,
108
+ title="API request failed",
109
+ message=f"Failed to get Docker service token from Vellum API (HTTP {e.status_code}).",
110
+ suggestion="Please check your configuration and try again. If the problem persists, "
111
+ "contact support.",
112
+ )
113
+ return
86
114
 
87
115
  docker_client.login(
88
116
  username="oauth2accesstoken",
@@ -143,11 +171,38 @@ def image_push_command(image: str, tags: Optional[List[str]] = None, workspace:
143
171
 
144
172
  logger.info(f"Updating Vellum metadata and validating image works in our system with image digest: {sha}...")
145
173
 
146
- vellum_client.container_images.push_container_image(
147
- name=image_name,
148
- sha=sha,
149
- tags=all_tags,
150
- )
174
+ try:
175
+ vellum_client.container_images.push_container_image(
176
+ name=image_name,
177
+ sha=sha,
178
+ tags=all_tags,
179
+ )
180
+ except ApiError as e:
181
+ if e.status_code == 401 or e.status_code == 403:
182
+ handle_cli_error(
183
+ logger,
184
+ title="Authentication failed",
185
+ message="Unable to push container image metadata to Vellum API. Please check your API key.",
186
+ suggestion="Make sure your VELLUM_API_KEY environment variable is set correctly.",
187
+ )
188
+ return
189
+ elif e.status_code == 500:
190
+ handle_cli_error(
191
+ logger,
192
+ title="Server error",
193
+ message="The Vellum API failed with an unexpected server error while pushing container image metadata.",
194
+ suggestion="Please try again later and contact support if the problem persists.",
195
+ )
196
+ return
197
+ else:
198
+ handle_cli_error(
199
+ logger,
200
+ title="API request failed",
201
+ message=f"Failed to push container image metadata to Vellum API (HTTP {e.status_code}).",
202
+ suggestion="Please check your configuration and try again. If the problem persists, contact support.",
203
+ )
204
+ return
205
+
151
206
  logger.info(f"Image successfully pushed as {image_name} to vellum with tags: {all_tags}.")
152
207
 
153
208