vellum-ai 0.14.14__py3-none-any.whl → 0.14.16__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/client/core/pydantic_utilities.py +4 -5
- vellum/client/resources/document_indexes/client.py +0 -55
- vellum/client/types/document_index_read.py +0 -10
- vellum/client/types/logical_operator.py +1 -0
- vellum/plugins/pydantic.py +14 -4
- vellum/workflows/nodes/core/retry_node/tests/test_node.py +23 -0
- vellum/workflows/nodes/displayable/api_node/tests/test_api_node.py +29 -0
- vellum/workflows/nodes/displayable/bases/api_node/node.py +2 -2
- vellum/workflows/vellum_client.py +9 -5
- {vellum_ai-0.14.14.dist-info → vellum_ai-0.14.16.dist-info}/METADATA +2 -2
- {vellum_ai-0.14.14.dist-info → vellum_ai-0.14.16.dist-info}/RECORD +33 -32
- vellum_cli/image_push.py +76 -42
- vellum_cli/tests/test_image_push.py +56 -0
- vellum_ee/workflows/display/nodes/base_node_display.py +8 -5
- vellum_ee/workflows/display/nodes/base_node_vellum_display.py +1 -4
- vellum_ee/workflows/display/nodes/get_node_display_class.py +34 -8
- vellum_ee/workflows/display/nodes/vellum/base_adornment_node.py +55 -1
- vellum_ee/workflows/display/nodes/vellum/retry_node.py +1 -54
- vellum_ee/workflows/display/nodes/vellum/templating_node.py +1 -8
- vellum_ee/workflows/display/nodes/vellum/try_node.py +1 -42
- vellum_ee/workflows/display/tests/test_vellum_workflow_display.py +47 -10
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +29 -33
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +91 -106
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py +33 -38
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py +197 -145
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py +23 -26
- vellum_ee/workflows/display/utils/vellum.py +3 -0
- vellum_ee/workflows/display/workflows/base_workflow_display.py +3 -6
- vellum_ee/workflows/display/workflows/tests/test_workflow_display.py +52 -0
- {vellum_ai-0.14.14.dist-info → vellum_ai-0.14.16.dist-info}/LICENSE +0 -0
- {vellum_ai-0.14.14.dist-info → vellum_ai-0.14.16.dist-info}/WHEEL +0 -0
- {vellum_ai-0.14.14.dist-info → vellum_ai-0.14.16.dist-info}/entry_points.txt +0 -0
    
        vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py
    CHANGED
    
    | @@ -9,16 +9,15 @@ class Inputs(BaseInputs): | |
| 9 9 | 
             
                input: str
         | 
| 10 10 |  | 
| 11 11 |  | 
| 12 | 
            -
            class BasicGenericNode(BaseNode):
         | 
| 13 | 
            -
                pass
         | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 12 | 
             
            def test_serialize_node__basic(serialize_node):
         | 
| 13 | 
            +
                class BasicGenericNode(BaseNode):
         | 
| 14 | 
            +
                    pass
         | 
| 15 | 
            +
             | 
| 17 16 | 
             
                serialized_node = serialize_node(BasicGenericNode)
         | 
| 18 17 | 
             
                assert not DeepDiff(
         | 
| 19 18 | 
             
                    {
         | 
| 20 | 
            -
                        "id": " | 
| 21 | 
            -
                        "label": "BasicGenericNode",
         | 
| 19 | 
            +
                        "id": "8d7cbfe4-72ca-4367-a401-8d28723d2f00",
         | 
| 20 | 
            +
                        "label": "test_serialize_node__basic.<locals>.BasicGenericNode",
         | 
| 22 21 | 
             
                        "type": "GENERIC",
         | 
| 23 22 | 
             
                        "display_data": {"position": {"x": 0.0, "y": 0.0}},
         | 
| 24 23 | 
             
                        "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
         | 
| @@ -34,10 +33,10 @@ def test_serialize_node__basic(serialize_node): | |
| 34 33 | 
             
                                "test_trigger_serialization",
         | 
| 35 34 | 
             
                            ],
         | 
| 36 35 | 
             
                        },
         | 
| 37 | 
            -
                        "trigger": {"id": " | 
| 36 | 
            +
                        "trigger": {"id": "be19c63b-3492-46b1-be9d-16f8d2e6410b", "merge_behavior": "AWAIT_ATTRIBUTES"},
         | 
| 38 37 | 
             
                        "ports": [
         | 
| 39 38 | 
             
                            {
         | 
| 40 | 
            -
                                "id": " | 
| 39 | 
            +
                                "id": "8bec8d0c-113f-4110-afcb-4a6e566e7236",
         | 
| 41 40 | 
             
                                "name": "default",
         | 
| 42 41 | 
             
                                "type": "DEFAULT",
         | 
| 43 42 | 
             
                            }
         | 
| @@ -51,17 +50,16 @@ def test_serialize_node__basic(serialize_node): | |
| 51 50 | 
             
                )
         | 
| 52 51 |  | 
| 53 52 |  | 
| 54 | 
            -
            class AwaitAnyGenericNode(BaseNode):
         | 
| 55 | 
            -
                class Trigger(BaseNode.Trigger):
         | 
| 56 | 
            -
                    merge_behavior = MergeBehavior.AWAIT_ANY
         | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 53 | 
             
            def test_serialize_node__await_any(serialize_node):
         | 
| 54 | 
            +
                class AwaitAnyGenericNode(BaseNode):
         | 
| 55 | 
            +
                    class Trigger(BaseNode.Trigger):
         | 
| 56 | 
            +
                        merge_behavior = MergeBehavior.AWAIT_ANY
         | 
| 57 | 
            +
             | 
| 60 58 | 
             
                serialized_node = serialize_node(AwaitAnyGenericNode)
         | 
| 61 59 | 
             
                assert not DeepDiff(
         | 
| 62 60 | 
             
                    {
         | 
| 63 | 
            -
                        "id": " | 
| 64 | 
            -
                        "label": "AwaitAnyGenericNode",
         | 
| 61 | 
            +
                        "id": "42e17f0e-8496-415f-9c72-f85250ba6f0b",
         | 
| 62 | 
            +
                        "label": "test_serialize_node__await_any.<locals>.AwaitAnyGenericNode",
         | 
| 65 63 | 
             
                        "type": "GENERIC",
         | 
| 66 64 | 
             
                        "display_data": {"position": {"x": 0.0, "y": 0.0}},
         | 
| 67 65 | 
             
                        "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
         | 
| @@ -77,10 +75,10 @@ def test_serialize_node__await_any(serialize_node): | |
| 77 75 | 
             
                                "test_trigger_serialization",
         | 
| 78 76 | 
             
                            ],
         | 
| 79 77 | 
             
                        },
         | 
| 80 | 
            -
                        "trigger": {"id": " | 
| 78 | 
            +
                        "trigger": {"id": "5bb6bb4c-4374-44c8-a7b5-7bb6c1060a5b", "merge_behavior": "AWAIT_ANY"},
         | 
| 81 79 | 
             
                        "ports": [
         | 
| 82 80 | 
             
                            {
         | 
| 83 | 
            -
                                "id": " | 
| 81 | 
            +
                                "id": "d9a84db7-8bd6-4a15-9e3c-c2e898c26d16",
         | 
| 84 82 | 
             
                                "name": "default",
         | 
| 85 83 | 
             
                                "type": "DEFAULT",
         | 
| 86 84 | 
             
                            }
         | 
| @@ -94,17 +92,16 @@ def test_serialize_node__await_any(serialize_node): | |
| 94 92 | 
             
                )
         | 
| 95 93 |  | 
| 96 94 |  | 
| 97 | 
            -
            class AwaitAllGenericNode(BaseNode):
         | 
| 98 | 
            -
                class Trigger(BaseNode.Trigger):
         | 
| 99 | 
            -
                    merge_behavior = MergeBehavior.AWAIT_ALL
         | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 95 | 
             
            def test_serialize_node__await_all(serialize_node):
         | 
| 96 | 
            +
                class AwaitAllGenericNode(BaseNode):
         | 
| 97 | 
            +
                    class Trigger(BaseNode.Trigger):
         | 
| 98 | 
            +
                        merge_behavior = MergeBehavior.AWAIT_ALL
         | 
| 99 | 
            +
             | 
| 103 100 | 
             
                serialized_node = serialize_node(AwaitAllGenericNode)
         | 
| 104 101 | 
             
                assert not DeepDiff(
         | 
| 105 102 | 
             
                    {
         | 
| 106 | 
            -
                        "id": " | 
| 107 | 
            -
                        "label": "AwaitAllGenericNode",
         | 
| 103 | 
            +
                        "id": "b3e1145a-5f41-456b-9382-6d0a1e828c2f",
         | 
| 104 | 
            +
                        "label": "test_serialize_node__await_all.<locals>.AwaitAllGenericNode",
         | 
| 108 105 | 
             
                        "type": "GENERIC",
         | 
| 109 106 | 
             
                        "display_data": {"position": {"x": 0.0, "y": 0.0}},
         | 
| 110 107 | 
             
                        "base": {"name": "BaseNode", "module": ["vellum", "workflows", "nodes", "bases", "base"]},
         | 
| @@ -120,10 +117,10 @@ def test_serialize_node__await_all(serialize_node): | |
| 120 117 | 
             
                                "test_trigger_serialization",
         | 
| 121 118 | 
             
                            ],
         | 
| 122 119 | 
             
                        },
         | 
| 123 | 
            -
                        "trigger": {"id": " | 
| 120 | 
            +
                        "trigger": {"id": "124ba9cf-a30e-41ef-81bf-143708f8b1c3", "merge_behavior": "AWAIT_ALL"},
         | 
| 124 121 | 
             
                        "ports": [
         | 
| 125 122 | 
             
                            {
         | 
| 126 | 
            -
                                "id": " | 
| 123 | 
            +
                                "id": "fa73da35-0bf9-4f02-bf5b-0b0d1a6f1494",
         | 
| 127 124 | 
             
                                "name": "default",
         | 
| 128 125 | 
             
                                "type": "DEFAULT",
         | 
| 129 126 | 
             
                            }
         | 
| @@ -28,6 +28,7 @@ from vellum.workflows.expressions.less_than_or_equal_to import LessThanOrEqualTo | |
| 28 28 | 
             
            from vellum.workflows.expressions.not_between import NotBetweenExpression
         | 
| 29 29 | 
             
            from vellum.workflows.expressions.not_in import NotInExpression
         | 
| 30 30 | 
             
            from vellum.workflows.expressions.or_ import OrExpression
         | 
| 31 | 
            +
            from vellum.workflows.expressions.parse_json import ParseJsonExpression
         | 
| 31 32 | 
             
            from vellum.workflows.nodes.bases.base import BaseNode
         | 
| 32 33 | 
             
            from vellum.workflows.nodes.displayable.bases.utils import primitive_to_vellum_value
         | 
| 33 34 | 
             
            from vellum.workflows.references import OutputReference, WorkflowInputReference
         | 
| @@ -163,5 +164,7 @@ def convert_descriptor_to_operator(descriptor: BaseDescriptor) -> LogicalOperato | |
| 163 164 | 
             
                    return "or"
         | 
| 164 165 | 
             
                elif isinstance(descriptor, CoalesceExpression):
         | 
| 165 166 | 
             
                    return "coalesce"
         | 
| 167 | 
            +
                elif isinstance(descriptor, ParseJsonExpression):
         | 
| 168 | 
            +
                    return "parseJson"
         | 
| 166 169 | 
             
                else:
         | 
| 167 170 | 
             
                    raise ValueError(f"Unsupported descriptor type: {descriptor}")
         | 
| @@ -212,8 +212,6 @@ class BaseWorkflowDisplay( | |
| 212 212 |  | 
| 213 213 | 
             
                    port_displays: Dict[Port, PortDisplay] = {}
         | 
| 214 214 |  | 
| 215 | 
            -
                    # TODO: We should still serialize nodes that are in the workflow's directory but aren't used in the graph.
         | 
| 216 | 
            -
                    # https://app.shortcut.com/vellum/story/5394
         | 
| 217 215 | 
             
                    for node in self._workflow.get_nodes():
         | 
| 218 216 | 
             
                        extracted_node_displays = self._extract_node_displays(node)
         | 
| 219 217 |  | 
| @@ -403,11 +401,11 @@ class BaseWorkflowDisplay( | |
| 403 401 | 
             
                        for input in display_context.workflow_input_displays
         | 
| 404 402 | 
             
                    }
         | 
| 405 403 | 
             
                    node_displays = {
         | 
| 406 | 
            -
                         | 
| 404 | 
            +
                        node.__id__: (node, display_context.node_displays[node]) for node in display_context.node_displays
         | 
| 407 405 | 
             
                    }
         | 
| 408 406 | 
             
                    node_event_displays = {}
         | 
| 409 407 | 
             
                    for node_id in node_displays:
         | 
| 410 | 
            -
                        current_node_display = node_displays[node_id]
         | 
| 408 | 
            +
                        node, current_node_display = node_displays[node_id]
         | 
| 411 409 | 
             
                        input_display = {}
         | 
| 412 410 | 
             
                        if isinstance(current_node_display, BaseNodeVellumDisplay):
         | 
| 413 411 | 
             
                            input_display = current_node_display.node_input_ids_by_name
         | 
| @@ -418,7 +416,6 @@ class BaseWorkflowDisplay( | |
| 418 416 | 
             
                        port_display_meta = {
         | 
| 419 417 | 
             
                            port.name: current_node_display.port_displays[port].id for port in current_node_display.port_displays
         | 
| 420 418 | 
             
                        }
         | 
| 421 | 
            -
                        node = current_node_display._node
         | 
| 422 419 | 
             
                        subworkflow_display_context: Optional[WorkflowEventDisplayContext] = None
         | 
| 423 420 | 
             
                        if hasattr(node, "subworkflow"):
         | 
| 424 421 | 
             
                            # All nodes that have a subworkflow attribute are currently expected to call them `subworkflow`
         | 
| @@ -432,7 +429,7 @@ class BaseWorkflowDisplay( | |
| 432 429 | 
             
                                )
         | 
| 433 430 | 
             
                                subworkflow_display_context = subworkflow_display.get_event_display_context()
         | 
| 434 431 |  | 
| 435 | 
            -
                        node_event_displays[node_id] = NodeEventDisplayContext(
         | 
| 432 | 
            +
                        node_event_displays[str(node_id)] = NodeEventDisplayContext(
         | 
| 436 433 | 
             
                            input_display=input_display,
         | 
| 437 434 | 
             
                            output_display=output_display,
         | 
| 438 435 | 
             
                            port_display=port_display_meta,
         | 
| @@ -1,9 +1,13 @@ | |
| 1 1 | 
             
            import pytest
         | 
| 2 | 
            +
            from uuid import uuid4
         | 
| 2 3 |  | 
| 3 4 | 
             
            from vellum.workflows.nodes.bases.base import BaseNode
         | 
| 4 5 | 
             
            from vellum.workflows.nodes.core.inline_subworkflow_node.node import InlineSubworkflowNode
         | 
| 6 | 
            +
            from vellum.workflows.nodes.core.retry_node.node import RetryNode
         | 
| 7 | 
            +
            from vellum.workflows.nodes.core.templating_node.node import TemplatingNode
         | 
| 5 8 | 
             
            from vellum.workflows.workflows.base import BaseWorkflow
         | 
| 6 9 | 
             
            from vellum_ee.workflows.display.nodes import BaseNodeDisplay
         | 
| 10 | 
            +
            from vellum_ee.workflows.display.nodes.vellum.retry_node import BaseRetryNodeDisplay
         | 
| 7 11 | 
             
            from vellum_ee.workflows.display.vellum import NodeDisplayData, NodeDisplayPosition
         | 
| 8 12 | 
             
            from vellum_ee.workflows.display.workflows import VellumWorkflowDisplay
         | 
| 9 13 | 
             
            from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
         | 
| @@ -139,3 +143,51 @@ def test_get_event_display_context__node_display_to_include_subworkflow_display( | |
| 139 143 |  | 
| 140 144 | 
             
                assert node_event_display.subworkflow_display is not None
         | 
| 141 145 | 
             
                assert str(InnerNode.__id__) in node_event_display.subworkflow_display.node_displays
         | 
| 146 | 
            +
             | 
| 147 | 
            +
             | 
| 148 | 
            +
            def test_get_event_display_context__node_display_for_adornment_nodes():
         | 
| 149 | 
            +
                # GIVEN a simple workflow with a retry node adornment
         | 
| 150 | 
            +
                @RetryNode.wrap(max_attempts=4)
         | 
| 151 | 
            +
                class MyNode(BaseNode):
         | 
| 152 | 
            +
                    pass
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                class MyWorkflow(BaseWorkflow):
         | 
| 155 | 
            +
                    graph = MyNode
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                # AND a display class for the node
         | 
| 158 | 
            +
                inner_node_id = uuid4()
         | 
| 159 | 
            +
             | 
| 160 | 
            +
                @BaseRetryNodeDisplay.wrap()
         | 
| 161 | 
            +
                class MyNodeDisplay(BaseNodeDisplay[MyNode]):
         | 
| 162 | 
            +
                    node_id = inner_node_id
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                # WHEN we gather the event display context
         | 
| 165 | 
            +
                display_context = VellumWorkflowDisplay(MyWorkflow).get_event_display_context()
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                # THEN the subworkflow display should be included
         | 
| 168 | 
            +
                assert str(MyNode.__id__) in display_context.node_displays
         | 
| 169 | 
            +
                node_event_display = display_context.node_displays[str(MyNode.__id__)]
         | 
| 170 | 
            +
                assert node_event_display.subworkflow_display is not None
         | 
| 171 | 
            +
                assert str(inner_node_id) in node_event_display.subworkflow_display.node_displays
         | 
| 172 | 
            +
             | 
| 173 | 
            +
             | 
| 174 | 
            +
            def test_get_event_display_context__templating_node_input_display():
         | 
| 175 | 
            +
                # GIVEN a simple workflow with a templating node referencing another node output
         | 
| 176 | 
            +
                class DataNode(BaseNode):
         | 
| 177 | 
            +
                    class Outputs:
         | 
| 178 | 
            +
                        bar: str
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                class MyNode(TemplatingNode):
         | 
| 181 | 
            +
                    inputs = {"foo": DataNode.Outputs.bar}
         | 
| 182 | 
            +
             | 
| 183 | 
            +
                class MyWorkflow(BaseWorkflow):
         | 
| 184 | 
            +
                    graph = DataNode >> MyNode
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                # WHEN we gather the event display context
         | 
| 187 | 
            +
                display_context = VellumWorkflowDisplay(MyWorkflow).get_event_display_context()
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                # THEN the subworkflow display should be included
         | 
| 190 | 
            +
                assert str(MyNode.__id__) in display_context.node_displays
         | 
| 191 | 
            +
                node_event_display = display_context.node_displays[str(MyNode.__id__)]
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                assert node_event_display.input_display.keys() == {"inputs.foo"}
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |