vellum-ai 0.14.70__py3-none-any.whl → 0.14.72__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/plugins/vellum_mypy.py +1 -1
- vellum/workflows/environment/environment.py +5 -2
- vellum/workflows/events/__init__.py +2 -0
- vellum/workflows/events/stream.py +28 -0
- vellum/workflows/events/workflow.py +3 -2
- vellum/workflows/nodes/displayable/code_execution_node/node.py +8 -1
- vellum/workflows/nodes/displayable/code_execution_node/tests/test_node.py +53 -0
- vellum/workflows/nodes/experimental/tool_calling_node/node.py +1 -1
- vellum/workflows/nodes/experimental/tool_calling_node/utils.py +2 -2
- vellum/workflows/references/environment_variable.py +11 -8
- vellum/workflows/runner/runner.py +21 -3
- vellum/workflows/utils/functions.py +55 -1
- vellum/workflows/utils/tests/test_functions.py +151 -1
- vellum/workflows/utils/tests/test_vellum_variables.py +25 -1
- vellum/workflows/utils/vellum_variables.py +30 -0
- vellum/workflows/workflows/base.py +11 -5
- {vellum_ai-0.14.70.dist-info → vellum_ai-0.14.72.dist-info}/METADATA +1 -1
- {vellum_ai-0.14.70.dist-info → vellum_ai-0.14.72.dist-info}/RECORD +34 -31
- vellum_cli/image_push.py +1 -5
- vellum_cli/push.py +7 -0
- vellum_cli/tests/test_image_push.py +1 -2
- vellum_cli/tests/test_push.py +33 -2
- vellum_ee/workflows/display/nodes/utils.py +2 -2
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +7 -3
- vellum_ee/workflows/display/nodes/vellum/search_node.py +69 -6
- vellum_ee/workflows/display/nodes/vellum/tests/test_search_node.py +104 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_prompt_node_serialization.py +82 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_search_node_serialization.py +4 -4
- vellum_ee/workflows/display/tests/workflow_serialization/test_workflow_input_parameterization_error.py +37 -0
- vellum_ee/workflows/display/utils/expressions.py +10 -1
- {vellum_ai-0.14.70.dist-info → vellum_ai-0.14.72.dist-info}/LICENSE +0 -0
- {vellum_ai-0.14.70.dist-info → vellum_ai-0.14.72.dist-info}/WHEEL +0 -0
- {vellum_ai-0.14.70.dist-info → vellum_ai-0.14.72.dist-info}/entry_points.txt +0 -0
@@ -174,6 +174,34 @@ def test_serialize_workflow():
|
|
174
174
|
"name": "ml_model",
|
175
175
|
"value": {"type": "CONSTANT_VALUE", "value": {"type": "STRING", "value": "gpt-4o"}},
|
176
176
|
},
|
177
|
+
{
|
178
|
+
"id": "25f935f3-363f-4ead-a5a0-db234ca67e1e",
|
179
|
+
"name": "blocks",
|
180
|
+
"value": {
|
181
|
+
"type": "CONSTANT_VALUE",
|
182
|
+
"value": {
|
183
|
+
"type": "JSON",
|
184
|
+
"value": [
|
185
|
+
{
|
186
|
+
"block_type": "CHAT_MESSAGE",
|
187
|
+
"state": None,
|
188
|
+
"cache_config": None,
|
189
|
+
"chat_role": "SYSTEM",
|
190
|
+
"chat_source": None,
|
191
|
+
"chat_message_unterminated": None,
|
192
|
+
"blocks": [
|
193
|
+
{
|
194
|
+
"block_type": "JINJA",
|
195
|
+
"state": None,
|
196
|
+
"cache_config": None,
|
197
|
+
"template": "What's your favorite {{noun}}?",
|
198
|
+
}
|
199
|
+
],
|
200
|
+
}
|
201
|
+
],
|
202
|
+
},
|
203
|
+
},
|
204
|
+
},
|
177
205
|
{
|
178
206
|
"id": "ffabe7d2-8ab6-4201-9d41-c4d7be1386e1",
|
179
207
|
"name": "prompt_inputs",
|
@@ -355,3 +383,57 @@ def test_serialize_workflow_with_descriptor_functions():
|
|
355
383
|
"node_output_id": "470fadb9-b8b5-477e-a502-5209d398bcf9",
|
356
384
|
"type": "NODE_OUTPUT",
|
357
385
|
}
|
386
|
+
|
387
|
+
|
388
|
+
def test_serialize_workflow_with_descriptor_blocks():
|
389
|
+
"""Test that serialization handles BaseDescriptor instances in blocks list."""
|
390
|
+
|
391
|
+
class TestInputs(BaseInputs):
|
392
|
+
noun: str
|
393
|
+
|
394
|
+
class UpstreamNode(BaseNode):
|
395
|
+
class Outputs(BaseNode.Outputs):
|
396
|
+
results: list
|
397
|
+
|
398
|
+
def run(self) -> Outputs:
|
399
|
+
return self.Outputs(results=["test"])
|
400
|
+
|
401
|
+
class TestInlinePromptNodeWithDescriptorBlocks(InlinePromptNode):
|
402
|
+
ml_model = "gpt-4o"
|
403
|
+
blocks = [UpstreamNode.Outputs.results[0]] # type: ignore
|
404
|
+
prompt_inputs = {"noun": TestInputs.noun}
|
405
|
+
|
406
|
+
class TestWorkflow(BaseWorkflow[TestInputs, BaseState]):
|
407
|
+
graph = UpstreamNode >> TestInlinePromptNodeWithDescriptorBlocks
|
408
|
+
|
409
|
+
workflow_display = get_workflow_display(workflow_class=TestWorkflow)
|
410
|
+
serialized: dict = workflow_display.serialize()
|
411
|
+
|
412
|
+
prompt_nodes = [node for node in serialized["workflow_raw_data"]["nodes"] if node["type"] == "PROMPT"]
|
413
|
+
prompt_node = prompt_nodes[0]
|
414
|
+
|
415
|
+
blocks = prompt_node["data"]["exec_config"]["prompt_template_block_data"]["blocks"]
|
416
|
+
descriptor_blocks = [block for block in blocks if not isinstance(block, dict) or not block.get("block_type")]
|
417
|
+
assert len(descriptor_blocks) == 0, "BaseDescriptor blocks should not appear in serialized blocks"
|
418
|
+
|
419
|
+
blocks_attr = next((attr for attr in prompt_node["attributes"] if attr["name"] == "blocks"), None)
|
420
|
+
assert blocks_attr is not None, "blocks attribute should be present when blocks contain BaseDescriptor"
|
421
|
+
assert blocks_attr["value"]["type"] == "ARRAY_REFERENCE", "blocks attribute should be serialized as ARRAY_REFERENCE"
|
422
|
+
assert blocks_attr["value"]["items"] == [
|
423
|
+
{
|
424
|
+
"type": "BINARY_EXPRESSION",
|
425
|
+
"lhs": {
|
426
|
+
"type": "NODE_OUTPUT",
|
427
|
+
"node_id": str(UpstreamNode.__id__),
|
428
|
+
"node_output_id": str(UpstreamNode.__output_ids__["results"]),
|
429
|
+
},
|
430
|
+
"operator": "accessField",
|
431
|
+
"rhs": {
|
432
|
+
"type": "CONSTANT_VALUE",
|
433
|
+
"value": {
|
434
|
+
"type": "NUMBER",
|
435
|
+
"value": 0.0,
|
436
|
+
},
|
437
|
+
},
|
438
|
+
}
|
439
|
+
]
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_search_node_serialization.py
CHANGED
@@ -167,7 +167,7 @@ def test_serialize_workflow():
|
|
167
167
|
"rules": [
|
168
168
|
{
|
169
169
|
"type": "INPUT_VARIABLE",
|
170
|
-
"data": {"input_variable_id": "
|
170
|
+
"data": {"input_variable_id": "b118247f-96dd-4b3e-8289-9f277483c520"},
|
171
171
|
}
|
172
172
|
],
|
173
173
|
"combinator": "OR",
|
@@ -180,7 +180,7 @@ def test_serialize_workflow():
|
|
180
180
|
"rules": [
|
181
181
|
{
|
182
182
|
"type": "INPUT_VARIABLE",
|
183
|
-
"data": {"input_variable_id": "
|
183
|
+
"data": {"input_variable_id": "aae2c10a-88b7-40bd-87a2-5e1e60c1e906"},
|
184
184
|
}
|
185
185
|
],
|
186
186
|
"combinator": "OR",
|
@@ -193,7 +193,7 @@ def test_serialize_workflow():
|
|
193
193
|
"rules": [
|
194
194
|
{
|
195
195
|
"type": "INPUT_VARIABLE",
|
196
|
-
"data": {"input_variable_id": "
|
196
|
+
"data": {"input_variable_id": "c9611a62-d1f5-4b41-bf9c-1aa3355760b4"},
|
197
197
|
}
|
198
198
|
],
|
199
199
|
"combinator": "OR",
|
@@ -206,7 +206,7 @@ def test_serialize_workflow():
|
|
206
206
|
"rules": [
|
207
207
|
{
|
208
208
|
"type": "INPUT_VARIABLE",
|
209
|
-
"data": {"input_variable_id": "
|
209
|
+
"data": {"input_variable_id": "f374640e-a5c0-470e-ac71-c36c2b198c00"},
|
210
210
|
}
|
211
211
|
],
|
212
212
|
"combinator": "OR",
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from vellum.workflows import BaseWorkflow
|
4
|
+
from vellum.workflows.inputs.base import BaseInputs
|
5
|
+
from vellum.workflows.nodes.bases.base import BaseNode
|
6
|
+
from vellum_ee.workflows.display.utils.exceptions import UnsupportedSerializationException
|
7
|
+
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
8
|
+
|
9
|
+
|
10
|
+
def test_workflow_serialization_error_when_node_references_unparameterized_inputs():
|
11
|
+
"""Test that a helpful error is raised when a node references inputs not parameterized by the workflow."""
|
12
|
+
|
13
|
+
class CustomInputs(BaseInputs):
|
14
|
+
custom_input: str
|
15
|
+
|
16
|
+
class TestNode(BaseNode):
|
17
|
+
class Outputs(BaseNode.Outputs):
|
18
|
+
output = CustomInputs.custom_input
|
19
|
+
|
20
|
+
class TestWorkflow(BaseWorkflow):
|
21
|
+
graph = TestNode
|
22
|
+
|
23
|
+
class Outputs(BaseWorkflow.Outputs):
|
24
|
+
result = TestNode.Outputs.output
|
25
|
+
|
26
|
+
workflow_display = get_workflow_display(workflow_class=TestWorkflow)
|
27
|
+
|
28
|
+
with pytest.raises(UnsupportedSerializationException) as exc_info:
|
29
|
+
workflow_display.serialize()
|
30
|
+
|
31
|
+
error_message = str(exc_info.value)
|
32
|
+
expected_message = (
|
33
|
+
"Inputs class 'CustomInputs' referenced during serialization of 'TestWorkflow' "
|
34
|
+
"without parameterizing this Workflow with this Inputs definition. "
|
35
|
+
"Update your Workflow definition to 'TestWorkflow(BaseWorkflow[CustomInputs, BaseState])'."
|
36
|
+
)
|
37
|
+
assert error_message == expected_message
|
@@ -211,7 +211,16 @@ def serialize_value(display_context: "WorkflowDisplayContext", value: Any) -> Js
|
|
211
211
|
return serialize_value(display_context, child_descriptor)
|
212
212
|
|
213
213
|
if isinstance(value, WorkflowInputReference):
|
214
|
-
|
214
|
+
try:
|
215
|
+
workflow_input_display = display_context.global_workflow_input_displays[value]
|
216
|
+
except KeyError:
|
217
|
+
inputs_class_name = value.inputs_class.__name__
|
218
|
+
workflow_class_name = display_context.workflow_display_class.infer_workflow_class().__name__
|
219
|
+
raise UnsupportedSerializationException(
|
220
|
+
f"Inputs class '{inputs_class_name}' referenced during serialization of '{workflow_class_name}' "
|
221
|
+
f"without parameterizing this Workflow with this Inputs definition. Update your Workflow "
|
222
|
+
f"definition to '{workflow_class_name}(BaseWorkflow[{inputs_class_name}, BaseState])'."
|
223
|
+
)
|
215
224
|
return {
|
216
225
|
"type": "WORKFLOW_INPUT",
|
217
226
|
"input_variable_id": str(workflow_input_display.id),
|
File without changes
|
File without changes
|
File without changes
|