vellum-ai 0.13.15__py3-none-any.whl → 0.13.18__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 (25) hide show
  1. vellum/client/core/client_wrapper.py +1 -1
  2. vellum/client/resources/workflows/client.py +0 -10
  3. vellum/workflows/nodes/core/templating_node/node.py +4 -47
  4. vellum/workflows/nodes/displayable/code_execution_node/node.py +29 -23
  5. vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +169 -5
  6. vellum/workflows/nodes/displayable/code_execution_node/utils.py +98 -1
  7. vellum/workflows/nodes/utils.py +50 -1
  8. vellum/workflows/references/external_input.py +14 -0
  9. vellum/workflows/state/base.py +7 -0
  10. vellum/workflows/state/tests/test_state.py +42 -0
  11. {vellum_ai-0.13.15.dist-info → vellum_ai-0.13.18.dist-info}/METADATA +1 -1
  12. {vellum_ai-0.13.15.dist-info → vellum_ai-0.13.18.dist-info}/RECORD +25 -24
  13. vellum_cli/pull.py +57 -20
  14. vellum_cli/push.py +1 -5
  15. vellum_cli/tests/test_pull.py +115 -8
  16. vellum_cli/tests/test_push.py +0 -8
  17. vellum_ee/workflows/display/nodes/base_node_display.py +2 -2
  18. vellum_ee/workflows/display/nodes/get_node_display_class.py +16 -20
  19. vellum_ee/workflows/display/nodes/vellum/__init__.py +2 -0
  20. vellum_ee/workflows/display/nodes/vellum/retry_node.py +10 -0
  21. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +23 -0
  22. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +2 -2
  23. {vellum_ai-0.13.15.dist-info → vellum_ai-0.13.18.dist-info}/LICENSE +0 -0
  24. {vellum_ai-0.13.15.dist-info → vellum_ai-0.13.18.dist-info}/WHEEL +0 -0
  25. {vellum_ai-0.13.15.dist-info → vellum_ai-0.13.18.dist-info}/entry_points.txt +0 -0
@@ -208,8 +208,8 @@ class BaseNodeDisplay(Generic[NodeType], metaclass=BaseNodeDisplayMeta):
208
208
  return uuid4_from_hash(f"{self.node_id}|trigger")
209
209
 
210
210
  @classmethod
211
- def get_from_node_display_registry(cls, node_class: Type[NodeType]) -> Type["BaseNodeDisplay"]:
212
- return cls._node_display_registry[node_class]
211
+ def get_from_node_display_registry(cls, node_class: Type[NodeType]) -> Optional[Type["BaseNodeDisplay"]]:
212
+ return cls._node_display_registry.get(node_class)
213
213
 
214
214
  @classmethod
215
215
  def infer_node_class(cls) -> Type[NodeType]:
@@ -10,27 +10,23 @@ if TYPE_CHECKING:
10
10
  def get_node_display_class(
11
11
  base_class: Type["NodeDisplayType"], node_class: Type[NodeType], root_node_class: Optional[Type[NodeType]] = None
12
12
  ) -> Type["NodeDisplayType"]:
13
- try:
14
- node_display_class = base_class.get_from_node_display_registry(node_class)
15
- except KeyError:
16
- try:
17
- base_node_display_class = get_node_display_class(
18
- base_class, node_class.__bases__[0], node_class if root_node_class is None else root_node_class
13
+ node_display_class = base_class.get_from_node_display_registry(node_class)
14
+ if node_display_class:
15
+ if not issubclass(node_display_class, base_class):
16
+ raise TypeError(
17
+ f"Expected to find a subclass of '{base_class.__name__}' for node class '{node_class.__name__}'"
19
18
  )
20
19
 
21
- # `base_node_display_class` is always a Generic class, so it's safe to index into it
22
- NodeDisplayBaseClass = base_node_display_class[node_class] # type: ignore[index]
23
- NodeDisplayClass = types.new_class(
24
- f"{node_class.__name__}Display",
25
- bases=(NodeDisplayBaseClass,),
26
- )
27
- return NodeDisplayClass
28
- except IndexError:
29
- return base_class
20
+ return node_display_class
30
21
 
31
- if not issubclass(node_display_class, base_class):
32
- raise TypeError(
33
- f"Expected to find a subclass of '{base_class.__name__}' for node class '{node_class.__name__}'"
34
- )
22
+ base_node_display_class = get_node_display_class(
23
+ base_class, node_class.__bases__[0], node_class if root_node_class is None else root_node_class
24
+ )
35
25
 
36
- return node_display_class
26
+ # `base_node_display_class` is always a Generic class, so it's safe to index into it
27
+ NodeDisplayBaseClass = base_node_display_class[node_class] # type: ignore[index]
28
+ NodeDisplayClass = types.new_class(
29
+ f"{node_class.__name__}Display",
30
+ bases=(NodeDisplayBaseClass,),
31
+ )
32
+ return NodeDisplayClass
@@ -10,6 +10,7 @@ from .map_node import BaseMapNodeDisplay
10
10
  from .merge_node import BaseMergeNodeDisplay
11
11
  from .note_node import BaseNoteNodeDisplay
12
12
  from .prompt_deployment_node import BasePromptDeploymentNodeDisplay
13
+ from .retry_node import BaseRetryNodeDisplay
13
14
  from .search_node import BaseSearchNodeDisplay
14
15
  from .subworkflow_deployment_node import BaseSubworkflowDeploymentNodeDisplay
15
16
  from .templating_node import BaseTemplatingNodeDisplay
@@ -17,6 +18,7 @@ from .try_node import BaseTryNodeDisplay
17
18
 
18
19
  # All node display classes must be imported here to be registered in BaseNodeDisplay's node display registry
19
20
  __all__ = [
21
+ "BaseRetryNodeDisplay",
20
22
  "BaseAPINodeDisplay",
21
23
  "BaseCodeExecutionNodeDisplay",
22
24
  "BaseConditionalNodeDisplay",
@@ -0,0 +1,10 @@
1
+ from typing import Generic, TypeVar
2
+
3
+ from vellum.workflows.nodes.core.retry_node.node import RetryNode
4
+ from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
5
+
6
+ _RetryNodeType = TypeVar("_RetryNodeType", bound=RetryNode)
7
+
8
+
9
+ class BaseRetryNodeDisplay(BaseNodeDisplay[_RetryNodeType], Generic[_RetryNodeType]):
10
+ pass
@@ -7,10 +7,13 @@ from vellum.workflows.nodes.bases.base import BaseNode
7
7
  from vellum.workflows.nodes.core.retry_node.node import RetryNode
8
8
  from vellum.workflows.nodes.core.try_node.node import TryNode
9
9
  from vellum.workflows.outputs.base import BaseOutputs
10
+ from vellum.workflows.workflows.base import BaseWorkflow
10
11
  from vellum_ee.workflows.display.base import WorkflowInputsDisplay
11
12
  from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
12
13
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
13
14
  from vellum_ee.workflows.display.nodes.vellum.try_node import BaseTryNodeDisplay
15
+ from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
16
+ from vellum_ee.workflows.display.workflows.vellum_workflow_display import VellumWorkflowDisplay
14
17
 
15
18
 
16
19
  class Inputs(BaseInputs):
@@ -110,6 +113,26 @@ def test_serialize_node__retry(serialize_node):
110
113
  )
111
114
 
112
115
 
116
+ def test_serialize_node__retry__no_display(): # GIVEN an adornment node
117
+ @RetryNode.wrap(max_attempts=5)
118
+ class StartNode(BaseNode):
119
+ pass
120
+
121
+ # AND a workflow that uses the adornment node
122
+ class MyWorkflow(BaseWorkflow):
123
+ graph = StartNode
124
+
125
+ # WHEN we serialize the workflow
126
+ workflow_display = get_workflow_display(
127
+ base_display_class=VellumWorkflowDisplay,
128
+ workflow_class=MyWorkflow,
129
+ )
130
+ exec_config = workflow_display.serialize()
131
+
132
+ # THEN the workflow display is created successfully
133
+ assert exec_config is not None
134
+
135
+
113
136
  @TryNode.wrap()
114
137
  class InnerTryGenericNode(BaseNode):
115
138
  input = Inputs.input
@@ -93,7 +93,7 @@ def test_serialize_workflow_with_filepath():
93
93
  "code_input_id": "f2e8a4fa-b54e-41e9-b314-0e5443519ac7",
94
94
  "runtime_input_id": "19d64948-f22b-4103-a7f5-3add184b31cc",
95
95
  "output_type": "NUMBER",
96
- "packages": [],
96
+ "packages": [{"name": "openai", "version": "1.0.0"}],
97
97
  "output_id": "0fde9607-353f-42c2-85c4-20f720ebc1ec",
98
98
  "log_output_id": "7cac05e3-b7c3-475e-8df8-422b496c3398",
99
99
  },
@@ -566,7 +566,7 @@ def test_serialize_workflow__try_wrapped():
566
566
  "code_input_id": "f2e8a4fa-b54e-41e9-b314-0e5443519ac7",
567
567
  "runtime_input_id": "19d64948-f22b-4103-a7f5-3add184b31cc",
568
568
  "output_type": "NUMBER",
569
- "packages": [],
569
+ "packages": [{"name": "openai", "version": "1.0.0"}],
570
570
  "output_id": "0fde9607-353f-42c2-85c4-20f720ebc1ec",
571
571
  "log_output_id": "7cac05e3-b7c3-475e-8df8-422b496c3398",
572
572
  },