vellum-ai 1.3.8__py3-none-any.whl → 1.3.9__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 +2 -2
- vellum/client/reference.md +71 -0
- vellum/client/resources/workflows/client.py +80 -0
- vellum/client/resources/workflows/raw_client.py +98 -0
- vellum/client/types/vellum_error.py +2 -1
- vellum/client/types/vellum_error_request.py +2 -1
- vellum/workflows/utils/tests/test_vellum_variables.py +7 -1
- vellum/workflows/utils/vellum_variables.py +42 -3
- {vellum_ai-1.3.8.dist-info → vellum_ai-1.3.9.dist-info}/METADATA +1 -1
- {vellum_ai-1.3.8.dist-info → vellum_ai-1.3.9.dist-info}/RECORD +33 -33
- vellum_ee/workflows/display/editor/types.py +2 -0
- vellum_ee/workflows/display/nodes/base_node_display.py +42 -14
- vellum_ee/workflows/display/nodes/tests/test_base_node_display.py +64 -0
- vellum_ee/workflows/display/nodes/vellum/final_output_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/retry_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/tests/test_prompt_node.py +12 -12
- vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py +4 -4
- vellum_ee/workflows/display/nodes/vellum/try_node.py +1 -1
- vellum_ee/workflows/display/tests/test_base_workflow_display.py +46 -0
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +1 -1
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_prompt_node_serialization.py +8 -8
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +1 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +1 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py +2 -1
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py +2 -1
- vellum_ee/workflows/display/utils/events.py +7 -1
- vellum_ee/workflows/display/utils/expressions.py +33 -19
- vellum_ee/workflows/display/utils/tests/test_events.py +4 -4
- vellum_ee/workflows/display/workflows/base_workflow_display.py +1 -1
- vellum_ee/workflows/display/workflows/tests/test_workflow_display.py +10 -10
- {vellum_ai-1.3.8.dist-info → vellum_ai-1.3.9.dist-info}/LICENSE +0 -0
- {vellum_ai-1.3.8.dist-info → vellum_ai-1.3.9.dist-info}/WHEEL +0 -0
- {vellum_ai-1.3.8.dist-info → vellum_ai-1.3.9.dist-info}/entry_points.txt +0 -0
@@ -2,6 +2,7 @@ from dataclasses import asdict, is_dataclass
|
|
2
2
|
import inspect
|
3
3
|
from io import StringIO
|
4
4
|
import sys
|
5
|
+
from uuid import UUID
|
5
6
|
from typing import TYPE_CHECKING, Any, Dict, List, cast
|
6
7
|
|
7
8
|
from pydantic import BaseModel
|
@@ -157,7 +158,9 @@ def get_child_descriptor(value: LazyReference, display_context: "WorkflowDisplay
|
|
157
158
|
return value._get()
|
158
159
|
|
159
160
|
|
160
|
-
def _serialize_condition(
|
161
|
+
def _serialize_condition(
|
162
|
+
executable_id: UUID, display_context: "WorkflowDisplayContext", condition: BaseDescriptor
|
163
|
+
) -> JsonObject:
|
161
164
|
if isinstance(
|
162
165
|
condition,
|
163
166
|
(
|
@@ -171,16 +174,16 @@ def _serialize_condition(display_context: "WorkflowDisplayContext", condition: B
|
|
171
174
|
ParseJsonExpression,
|
172
175
|
),
|
173
176
|
):
|
174
|
-
lhs = serialize_value(display_context, condition._expression)
|
177
|
+
lhs = serialize_value(executable_id, display_context, condition._expression)
|
175
178
|
return {
|
176
179
|
"type": "UNARY_EXPRESSION",
|
177
180
|
"lhs": lhs,
|
178
181
|
"operator": convert_descriptor_to_operator(condition),
|
179
182
|
}
|
180
183
|
elif isinstance(condition, (BetweenExpression, NotBetweenExpression)):
|
181
|
-
base = serialize_value(display_context, condition._value)
|
182
|
-
lhs = serialize_value(display_context, condition._start)
|
183
|
-
rhs = serialize_value(display_context, condition._end)
|
184
|
+
base = serialize_value(executable_id, display_context, condition._value)
|
185
|
+
lhs = serialize_value(executable_id, display_context, condition._start)
|
186
|
+
rhs = serialize_value(executable_id, display_context, condition._end)
|
184
187
|
|
185
188
|
return {
|
186
189
|
"type": "TERNARY_EXPRESSION",
|
@@ -214,8 +217,8 @@ def _serialize_condition(display_context: "WorkflowDisplayContext", condition: B
|
|
214
217
|
OrExpression,
|
215
218
|
),
|
216
219
|
):
|
217
|
-
lhs = serialize_value(display_context, condition._lhs)
|
218
|
-
rhs = serialize_value(display_context, condition._rhs)
|
220
|
+
lhs = serialize_value(executable_id, display_context, condition._lhs)
|
221
|
+
rhs = serialize_value(executable_id, display_context, condition._rhs)
|
219
222
|
|
220
223
|
return {
|
221
224
|
"type": "BINARY_EXPRESSION",
|
@@ -226,9 +229,9 @@ def _serialize_condition(display_context: "WorkflowDisplayContext", condition: B
|
|
226
229
|
elif isinstance(condition, AccessorExpression):
|
227
230
|
return {
|
228
231
|
"type": "BINARY_EXPRESSION",
|
229
|
-
"lhs": serialize_value(display_context, condition._base),
|
232
|
+
"lhs": serialize_value(executable_id, display_context, condition._base),
|
230
233
|
"operator": "accessField",
|
231
|
-
"rhs": serialize_value(display_context, condition._field),
|
234
|
+
"rhs": serialize_value(executable_id, display_context, condition._field),
|
232
235
|
}
|
233
236
|
|
234
237
|
raise UnsupportedSerializationException(f"Unsupported condition type: {condition.__class__.__name__}")
|
@@ -248,16 +251,27 @@ def serialize_key(key: Any) -> str:
|
|
248
251
|
_UNDEFINED_SENTINEL: JsonObject = {"__undefined__": True}
|
249
252
|
|
250
253
|
|
251
|
-
def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> JsonObject:
|
254
|
+
def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContext", value: Any) -> JsonObject:
|
255
|
+
"""
|
256
|
+
Serialize a value to a JSON object.
|
257
|
+
|
258
|
+
Args:
|
259
|
+
executable_id: node id or workflow id
|
260
|
+
display_context: workflow display context
|
261
|
+
value: value to serialize
|
262
|
+
|
263
|
+
Returns:
|
264
|
+
serialized value
|
265
|
+
"""
|
252
266
|
if value is undefined:
|
253
267
|
return _UNDEFINED_SENTINEL
|
254
268
|
|
255
269
|
if isinstance(value, ConstantValueReference):
|
256
|
-
return serialize_value(display_context, value._value)
|
270
|
+
return serialize_value(executable_id, display_context, value._value)
|
257
271
|
|
258
272
|
if isinstance(value, LazyReference):
|
259
273
|
child_descriptor = get_child_descriptor(value, display_context)
|
260
|
-
return serialize_value(display_context, child_descriptor)
|
274
|
+
return serialize_value(executable_id, display_context, child_descriptor)
|
261
275
|
|
262
276
|
if isinstance(value, WorkflowInputReference):
|
263
277
|
try:
|
@@ -324,7 +338,7 @@ def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> Js
|
|
324
338
|
if isinstance(value, list):
|
325
339
|
serialized_items = []
|
326
340
|
for item in value:
|
327
|
-
serialized_item = serialize_value(display_context, item)
|
341
|
+
serialized_item = serialize_value(executable_id, display_context, item)
|
328
342
|
if serialized_item != _UNDEFINED_SENTINEL:
|
329
343
|
serialized_items.append(serialized_item)
|
330
344
|
|
@@ -355,16 +369,16 @@ def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> Js
|
|
355
369
|
|
356
370
|
if is_dataclass(value) and not isinstance(value, type):
|
357
371
|
dict_value = asdict(value)
|
358
|
-
return serialize_value(display_context, dict_value)
|
372
|
+
return serialize_value(executable_id, display_context, dict_value)
|
359
373
|
|
360
374
|
if isinstance(value, dict):
|
361
375
|
serialized_entries: List[Dict[str, Any]] = []
|
362
376
|
for key, val in value.items():
|
363
|
-
serialized_val = serialize_value(display_context, val)
|
377
|
+
serialized_val = serialize_value(executable_id, display_context, val)
|
364
378
|
if serialized_val != _UNDEFINED_SENTINEL:
|
365
379
|
serialized_entries.append(
|
366
380
|
{
|
367
|
-
"id": str(uuid4_from_hash(f"{
|
381
|
+
"id": str(uuid4_from_hash(f"{executable_id}|{key}")),
|
368
382
|
"key": serialize_key(key),
|
369
383
|
"value": serialized_val,
|
370
384
|
}
|
@@ -434,7 +448,7 @@ def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> Js
|
|
434
448
|
|
435
449
|
if isinstance(value, BaseModel):
|
436
450
|
dict_value = value.model_dump()
|
437
|
-
return serialize_value(display_context, dict_value)
|
451
|
+
return serialize_value(executable_id, display_context, dict_value)
|
438
452
|
|
439
453
|
if callable(value):
|
440
454
|
function_definition = compile_function_definition(value)
|
@@ -447,7 +461,7 @@ def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> Js
|
|
447
461
|
if inputs:
|
448
462
|
serialized_inputs = {}
|
449
463
|
for param_name, input_ref in inputs.items():
|
450
|
-
serialized_inputs[param_name] = serialize_value(display_context, input_ref)
|
464
|
+
serialized_inputs[param_name] = serialize_value(executable_id, display_context, input_ref)
|
451
465
|
|
452
466
|
model_data = function_definition.model_dump()
|
453
467
|
model_data["inputs"] = serialized_inputs
|
@@ -485,4 +499,4 @@ def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> Js
|
|
485
499
|
|
486
500
|
# If it's not any of the references we know about,
|
487
501
|
# then try to serialize it as a nested value
|
488
|
-
return _serialize_condition(display_context, value)
|
502
|
+
return _serialize_condition(executable_id, display_context, value)
|
@@ -47,7 +47,7 @@ from vellum_ee.workflows.display.utils.events import event_enricher
|
|
47
47
|
),
|
48
48
|
],
|
49
49
|
)
|
50
|
-
def test_event_enricher_static_workflow(is_dynamic: bool, expected_config: Optional[dict]):
|
50
|
+
def test_event_enricher_static_workflow(vellum_client, is_dynamic: bool, expected_config: Optional[dict]):
|
51
51
|
"""Test event_enricher with a static workflow (is_dynamic=False)."""
|
52
52
|
# GIVEN a workflow class with the specified is_dynamic value
|
53
53
|
_is_dynamic = is_dynamic
|
@@ -65,7 +65,7 @@ def test_event_enricher_static_workflow(is_dynamic: bool, expected_config: Optio
|
|
65
65
|
)
|
66
66
|
|
67
67
|
# WHEN the event_enricher is called with mocked dependencies
|
68
|
-
event_enricher(event)
|
68
|
+
event_enricher(event, vellum_client)
|
69
69
|
|
70
70
|
# THEN workflow_version_exec_config is set to the expected config
|
71
71
|
assert event.body.workflow_version_exec_config == expected_config
|
@@ -76,7 +76,7 @@ def test_event_enricher_static_workflow(is_dynamic: bool, expected_config: Optio
|
|
76
76
|
assert hasattr(event.body.display_context, "workflow_outputs")
|
77
77
|
|
78
78
|
|
79
|
-
def test_event_enricher_marks_subworkflow_deployment_as_dynamic():
|
79
|
+
def test_event_enricher_marks_subworkflow_deployment_as_dynamic(vellum_client):
|
80
80
|
"""Test that event_enricher treats subworkflow deployments as dynamic."""
|
81
81
|
|
82
82
|
class TestWorkflow(BaseWorkflow):
|
@@ -110,7 +110,7 @@ def test_event_enricher_marks_subworkflow_deployment_as_dynamic():
|
|
110
110
|
),
|
111
111
|
)
|
112
112
|
|
113
|
-
enriched_event = event_enricher(event)
|
113
|
+
enriched_event = event_enricher(event, vellum_client)
|
114
114
|
|
115
115
|
assert hasattr(enriched_event.body, "workflow_version_exec_config")
|
116
116
|
assert enriched_event.body.workflow_version_exec_config is not None
|
@@ -302,7 +302,7 @@ class BaseWorkflowDisplay(Generic[WorkflowType]):
|
|
302
302
|
output_values.append(
|
303
303
|
{
|
304
304
|
"output_variable_id": str(workflow_output_display.id),
|
305
|
-
"value": serialize_value(self.display_context, workflow_output.instance),
|
305
|
+
"value": serialize_value(self.workflow_id, self.display_context, workflow_output.instance),
|
306
306
|
}
|
307
307
|
)
|
308
308
|
|
@@ -706,12 +706,12 @@ def test_serialize_workflow__dict_reference():
|
|
706
706
|
"type": "DICTIONARY_REFERENCE",
|
707
707
|
"entries": [
|
708
708
|
{
|
709
|
-
"id": "
|
709
|
+
"id": "7689f0df-e0bc-4e53-a63f-dbee027f58b9",
|
710
710
|
"key": "key1",
|
711
711
|
"value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "constant1"}},
|
712
712
|
},
|
713
713
|
{
|
714
|
-
"id": "
|
714
|
+
"id": "89e01555-b0b5-42d5-a0a7-bce72716cf65",
|
715
715
|
"key": "key2",
|
716
716
|
"value": {
|
717
717
|
"type": "NODE_OUTPUT",
|
@@ -720,12 +720,12 @@ def test_serialize_workflow__dict_reference():
|
|
720
720
|
},
|
721
721
|
},
|
722
722
|
{
|
723
|
-
"id": "
|
723
|
+
"id": "2dc84109-b85c-4732-aa60-8c10a1a377d2",
|
724
724
|
"key": "key3",
|
725
725
|
"value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "constant2"}},
|
726
726
|
},
|
727
727
|
{
|
728
|
-
"id": "
|
728
|
+
"id": "d1b3ce75-1b1e-45e3-b798-beafe6c4826f",
|
729
729
|
"key": "key4",
|
730
730
|
"value": {
|
731
731
|
"type": "NODE_OUTPUT",
|
@@ -745,18 +745,18 @@ def test_serialize_workflow__dict_reference():
|
|
745
745
|
"type": "DICTIONARY_REFERENCE",
|
746
746
|
"entries": [
|
747
747
|
{
|
748
|
-
"id": "
|
748
|
+
"id": "7689f0df-e0bc-4e53-a63f-dbee027f58b9",
|
749
749
|
"key": "key1",
|
750
750
|
"value": {
|
751
751
|
"type": "DICTIONARY_REFERENCE",
|
752
752
|
"entries": [
|
753
753
|
{
|
754
|
-
"id": "
|
754
|
+
"id": "7689f0df-e0bc-4e53-a63f-dbee027f58b9",
|
755
755
|
"key": "key1",
|
756
756
|
"value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "constant1"}},
|
757
757
|
},
|
758
758
|
{
|
759
|
-
"id": "
|
759
|
+
"id": "89e01555-b0b5-42d5-a0a7-bce72716cf65",
|
760
760
|
"key": "key2",
|
761
761
|
"value": {
|
762
762
|
"type": "NODE_OUTPUT",
|
@@ -768,18 +768,18 @@ def test_serialize_workflow__dict_reference():
|
|
768
768
|
},
|
769
769
|
},
|
770
770
|
{
|
771
|
-
"id": "
|
771
|
+
"id": "89e01555-b0b5-42d5-a0a7-bce72716cf65",
|
772
772
|
"key": "key2",
|
773
773
|
"value": {
|
774
774
|
"type": "DICTIONARY_REFERENCE",
|
775
775
|
"entries": [
|
776
776
|
{
|
777
|
-
"id": "
|
777
|
+
"id": "7689f0df-e0bc-4e53-a63f-dbee027f58b9",
|
778
778
|
"key": "key1",
|
779
779
|
"value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "constant2"}},
|
780
780
|
},
|
781
781
|
{
|
782
|
-
"id": "
|
782
|
+
"id": "89e01555-b0b5-42d5-a0a7-bce72716cf65",
|
783
783
|
"key": "key2",
|
784
784
|
"value": {
|
785
785
|
"type": "NODE_OUTPUT",
|
File without changes
|
File without changes
|
File without changes
|