vellum-ai 0.14.35__py3-none-any.whl → 0.14.37__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 (42) hide show
  1. vellum/__init__.py +6 -0
  2. vellum/client/__init__.py +4 -4
  3. vellum/client/core/client_wrapper.py +1 -1
  4. vellum/client/resources/release_reviews/client.py +118 -1
  5. vellum/client/types/__init__.py +6 -0
  6. vellum/client/types/logical_operator.py +1 -0
  7. vellum/client/types/prompt_deployment_release.py +34 -0
  8. vellum/client/types/prompt_deployment_release_prompt_deployment.py +19 -0
  9. vellum/client/types/prompt_deployment_release_prompt_version.py +19 -0
  10. vellum/types/prompt_deployment_release.py +3 -0
  11. vellum/types/prompt_deployment_release_prompt_deployment.py +3 -0
  12. vellum/types/prompt_deployment_release_prompt_version.py +3 -0
  13. vellum/workflows/inputs/base.py +2 -1
  14. vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +2 -0
  15. vellum/workflows/nodes/displayable/guardrail_node/node.py +35 -12
  16. vellum/workflows/nodes/displayable/guardrail_node/test_node.py +88 -0
  17. vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +14 -2
  18. vellum/workflows/nodes/displayable/prompt_deployment_node/tests/test_node.py +43 -0
  19. vellum/workflows/state/base.py +38 -3
  20. vellum/workflows/state/tests/test_state.py +49 -0
  21. vellum/workflows/workflows/base.py +17 -0
  22. vellum/workflows/workflows/tests/test_base_workflow.py +39 -0
  23. {vellum_ai-0.14.35.dist-info → vellum_ai-0.14.37.dist-info}/METADATA +1 -1
  24. {vellum_ai-0.14.35.dist-info → vellum_ai-0.14.37.dist-info}/RECORD +42 -35
  25. vellum_cli/pull.py +3 -0
  26. vellum_cli/tests/test_pull.py +3 -1
  27. vellum_ee/workflows/display/base.py +9 -7
  28. vellum_ee/workflows/display/nodes/__init__.py +2 -2
  29. vellum_ee/workflows/display/nodes/vellum/note_node.py +1 -2
  30. vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +2 -0
  31. vellum_ee/workflows/display/nodes/vellum/tests/test_note_node.py +33 -0
  32. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py +3 -4
  33. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_default_state_serialization.py +1 -1
  34. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +0 -1
  35. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_prompt_deployment_serialization.py +1 -0
  36. vellum_ee/workflows/display/types.py +6 -7
  37. vellum_ee/workflows/display/vellum.py +5 -4
  38. vellum_ee/workflows/display/workflows/base_workflow_display.py +20 -19
  39. vellum_ee/workflows/display/workflows/vellum_workflow_display.py +11 -37
  40. {vellum_ai-0.14.35.dist-info → vellum_ai-0.14.37.dist-info}/LICENSE +0 -0
  41. {vellum_ai-0.14.35.dist-info → vellum_ai-0.14.37.dist-info}/WHEEL +0 -0
  42. {vellum_ai-0.14.35.dist-info → vellum_ai-0.14.37.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,33 @@
1
+ from vellum.workflows import BaseWorkflow
2
+ from vellum.workflows.nodes.displayable.note_node.node import NoteNode
3
+ from vellum_ee.workflows.display.nodes.vellum.note_node import BaseNoteNodeDisplay
4
+ from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
5
+ from vellum_ee.workflows.display.workflows.vellum_workflow_display import VellumWorkflowDisplay
6
+
7
+
8
+ def test_serialize_node__note_node():
9
+ # GIVEN a note node
10
+ class MyNoteNode(NoteNode):
11
+ pass
12
+
13
+ # AND a display class for the note node
14
+ class MyNoteNodeDisplay(BaseNoteNodeDisplay[MyNoteNode]):
15
+ text = "This makes sense"
16
+ style = {
17
+ "fontSize": 24,
18
+ }
19
+
20
+ # AND a workflow with the code node
21
+ class Workflow(BaseWorkflow):
22
+ graph = MyNoteNode
23
+
24
+ # WHEN the workflow is serialized
25
+ workflow_display = get_workflow_display(base_display_class=VellumWorkflowDisplay, workflow_class=Workflow)
26
+ serialized_workflow: dict = workflow_display.serialize()
27
+
28
+ # THEN the node should properly serialize the inputs
29
+ my_note_node = next(node for node in serialized_workflow["workflow_raw_data"]["nodes"] if node["type"] == "NOTE")
30
+
31
+ assert my_note_node["inputs"] == []
32
+ assert my_note_node["data"]["text"] == "This makes sense"
33
+ assert my_note_node["data"]["style"] == {"fontSize": 24}
@@ -1,11 +1,9 @@
1
1
  import pytest
2
2
  from uuid import uuid4
3
- from typing import Any, Dict, Type
3
+ from typing import Any, Type
4
4
 
5
- from vellum.workflows.references.workflow_input import WorkflowInputReference
6
5
  from vellum.workflows.types.core import JsonObject
7
6
  from vellum.workflows.types.generics import NodeType
8
- from vellum_ee.workflows.display.base import WorkflowInputsDisplayType
9
7
  from vellum_ee.workflows.display.editor.types import NodeDisplayData
10
8
  from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
11
9
  from vellum_ee.workflows.display.nodes.get_node_display_class import get_node_display_class
@@ -14,6 +12,7 @@ from vellum_ee.workflows.display.types import (
14
12
  NodeOutputDisplays,
15
13
  StateValueDisplays,
16
14
  WorkflowDisplayContext,
15
+ WorkflowInputsDisplays,
17
16
  )
18
17
  from vellum_ee.workflows.display.vellum import WorkflowMetaVellumDisplay
19
18
  from vellum_ee.workflows.display.workflows.vellum_workflow_display import VellumWorkflowDisplay
@@ -24,7 +23,7 @@ def serialize_node():
24
23
  def _serialize_node(
25
24
  node_class: Type[NodeType],
26
25
  base_class: type[BaseNodeDisplay[Any]] = BaseNodeDisplay,
27
- global_workflow_input_displays: Dict[WorkflowInputReference, WorkflowInputsDisplayType] = {},
26
+ global_workflow_input_displays: WorkflowInputsDisplays = {},
28
27
  global_state_value_displays: StateValueDisplays = {},
29
28
  global_node_displays: NodeDisplays = {},
30
29
  global_node_output_displays: NodeOutputDisplays = {},
@@ -32,7 +32,7 @@ def test_serialize_workflow():
32
32
  "key": "example",
33
33
  "type": "STRING",
34
34
  "default": {"type": "STRING", "value": "hello"},
35
- "required": True,
35
+ "required": False,
36
36
  "extensions": {"color": None},
37
37
  },
38
38
  ],
@@ -70,7 +70,6 @@ def test_serialize_workflow():
70
70
  "source_handle_id": "844d992e-60ab-4af2-a8ff-52cd858386f7",
71
71
  },
72
72
  "base": None,
73
- "base": None,
74
73
  "definition": None,
75
74
  "display_data": {
76
75
  "position": {"x": 0.0, "y": 0.0},
@@ -144,6 +144,7 @@ def test_serialize_workflow(vellum_client):
144
144
  "variant": "DEPLOYMENT",
145
145
  "prompt_deployment_id": deployment.id,
146
146
  "release_tag": "LATEST",
147
+ "ml_model_fallbacks": ["gpt-4o", "gemini-1.5-pro"],
147
148
  },
148
149
  "display_data": {
149
150
  "position": {
@@ -1,5 +1,5 @@
1
1
  from dataclasses import dataclass, field
2
- from typing import TYPE_CHECKING, Dict, Generic, Tuple, Type, TypeVar
2
+ from typing import TYPE_CHECKING, Dict, Tuple, Type, TypeVar
3
3
 
4
4
  from vellum.workflows.descriptors.base import BaseDescriptor
5
5
  from vellum.workflows.events.workflow import WorkflowEventDisplayContext # noqa: F401
@@ -10,7 +10,7 @@ from vellum_ee.workflows.display.base import (
10
10
  EdgeDisplay,
11
11
  EntrypointDisplay,
12
12
  StateValueDisplay,
13
- WorkflowInputsDisplayType,
13
+ WorkflowInputsDisplay,
14
14
  WorkflowMetaDisplay,
15
15
  WorkflowOutputDisplay,
16
16
  )
@@ -22,6 +22,7 @@ if TYPE_CHECKING:
22
22
 
23
23
  WorkflowDisplayType = TypeVar("WorkflowDisplayType", bound="BaseWorkflowDisplay")
24
24
 
25
+ WorkflowInputsDisplays = Dict[WorkflowInputReference, WorkflowInputsDisplay]
25
26
  StateValueDisplays = Dict[StateValueReference, StateValueDisplay]
26
27
  NodeDisplays = Dict[Type[BaseNode], BaseNodeDisplay]
27
28
  NodeOutputDisplays = Dict[OutputReference, Tuple[Type[BaseNode], NodeOutputDisplay]]
@@ -32,13 +33,11 @@ PortDisplays = Dict[Port, PortDisplay]
32
33
 
33
34
 
34
35
  @dataclass
35
- class WorkflowDisplayContext(Generic[WorkflowInputsDisplayType,]):
36
+ class WorkflowDisplayContext:
36
37
  workflow_display_class: Type["BaseWorkflowDisplay"]
37
38
  workflow_display: WorkflowMetaDisplay
38
- workflow_input_displays: Dict[WorkflowInputReference, WorkflowInputsDisplayType] = field(default_factory=dict)
39
- global_workflow_input_displays: Dict[WorkflowInputReference, WorkflowInputsDisplayType] = field(
40
- default_factory=dict
41
- )
39
+ workflow_input_displays: WorkflowInputsDisplays = field(default_factory=dict)
40
+ global_workflow_input_displays: WorkflowInputsDisplays = field(default_factory=dict)
42
41
  state_value_displays: StateValueDisplays = field(default_factory=dict)
43
42
  global_state_value_displays: StateValueDisplays = field(default_factory=dict)
44
43
  node_displays: NodeDisplays = field(default_factory=dict)
@@ -8,7 +8,6 @@ from vellum_ee.workflows.display.base import (
8
8
  EntrypointDisplayOverrides,
9
9
  StateValueDisplayOverrides,
10
10
  WorkflowInputsDisplay,
11
- WorkflowInputsDisplayOverrides,
12
11
  WorkflowMetaDisplayOverrides,
13
12
  WorkflowOutputDisplayOverrides,
14
13
  )
@@ -44,10 +43,12 @@ class WorkflowMetaVellumDisplay(WorkflowMetaVellumDisplayOverrides):
44
43
 
45
44
 
46
45
  @dataclass
47
- class WorkflowInputsVellumDisplayOverrides(WorkflowInputsDisplay, WorkflowInputsDisplayOverrides):
48
- name: Optional[str] = None
46
+ class WorkflowInputsVellumDisplayOverrides(WorkflowInputsDisplay):
47
+ """
48
+ DEPRECATED: Use WorkflowInputsDisplay instead. Will be removed in 0.15.0
49
+ """
50
+
49
51
  required: Optional[bool] = None
50
- color: Optional[str] = None
51
52
 
52
53
 
53
54
  @dataclass
@@ -21,8 +21,7 @@ from vellum_ee.workflows.display.base import (
21
21
  EdgeDisplay,
22
22
  EntrypointDisplay,
23
23
  StateValueDisplay,
24
- WorkflowInputsDisplayOverridesType,
25
- WorkflowInputsDisplayType,
24
+ WorkflowInputsDisplay,
26
25
  WorkflowMetaDisplay,
27
26
  WorkflowOutputDisplay,
28
27
  )
@@ -40,6 +39,7 @@ from vellum_ee.workflows.display.types import (
40
39
  PortDisplays,
41
40
  StateValueDisplays,
42
41
  WorkflowDisplayContext,
42
+ WorkflowInputsDisplays,
43
43
  WorkflowOutputDisplays,
44
44
  )
45
45
  from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
@@ -47,18 +47,12 @@ from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class imp
47
47
  logger = logging.getLogger(__name__)
48
48
 
49
49
 
50
- class BaseWorkflowDisplay(
51
- Generic[
52
- WorkflowType,
53
- WorkflowInputsDisplayType,
54
- WorkflowInputsDisplayOverridesType,
55
- ]
56
- ):
50
+ class BaseWorkflowDisplay(Generic[WorkflowType]):
57
51
  # Used to specify the display data for a workflow.
58
52
  workflow_display: Optional[WorkflowMetaDisplay] = None
59
53
 
60
54
  # Used to explicitly specify display data for a workflow's inputs.
61
- inputs_display: Dict[WorkflowInputReference, WorkflowInputsDisplayOverridesType] = {}
55
+ inputs_display: WorkflowInputsDisplays = {}
62
56
 
63
57
  # Used to explicitly specify display data for a workflow's state values.
64
58
  state_value_displays: StateValueDisplays = {}
@@ -86,7 +80,7 @@ class BaseWorkflowDisplay(
86
80
  self,
87
81
  workflow: Type[WorkflowType],
88
82
  *,
89
- parent_display_context: Optional[WorkflowDisplayContext[WorkflowInputsDisplayType,]] = None,
83
+ parent_display_context: Optional[WorkflowDisplayContext] = None,
90
84
  dry_run: bool = False,
91
85
  ):
92
86
  self._workflow = workflow
@@ -174,9 +168,7 @@ class BaseWorkflowDisplay(
174
168
  return node_display
175
169
 
176
170
  @cached_property
177
- def display_context(
178
- self,
179
- ) -> WorkflowDisplayContext[WorkflowInputsDisplayType]:
171
+ def display_context(self) -> WorkflowDisplayContext:
180
172
  workflow_meta_display = self._generate_workflow_meta_display()
181
173
 
182
174
  global_node_output_displays: NodeOutputDisplays = (
@@ -209,7 +201,7 @@ class BaseWorkflowDisplay(
209
201
  port_displays=port_displays,
210
202
  )
211
203
 
212
- workflow_input_displays: Dict[WorkflowInputReference, WorkflowInputsDisplayType] = {}
204
+ workflow_input_displays: WorkflowInputsDisplays = {}
213
205
  # If we're dealing with a nested workflow, then it should have access to the inputs of its parents.
214
206
  global_workflow_input_displays = (
215
207
  copy(self._parent_display_context.workflow_input_displays) if self._parent_display_context else {}
@@ -311,11 +303,20 @@ class BaseWorkflowDisplay(
311
303
  entrypoint_node_display=NodeDisplayData(),
312
304
  )
313
305
 
314
- @abstractmethod
315
306
  def _generate_workflow_input_display(
316
- self, workflow_input: WorkflowInputReference, overrides: Optional[WorkflowInputsDisplayOverridesType] = None
317
- ) -> WorkflowInputsDisplayType:
318
- pass
307
+ self, workflow_input: WorkflowInputReference, overrides: Optional[WorkflowInputsDisplay] = None
308
+ ) -> WorkflowInputsDisplay:
309
+ workflow_input_id: UUID
310
+ name = None
311
+ color = None
312
+ if overrides:
313
+ workflow_input_id = overrides.id
314
+ name = overrides.name
315
+ color = overrides.color
316
+ else:
317
+ workflow_input_id = uuid4_from_hash(f"{self.workflow_id}|inputs|id|{workflow_input.name}")
318
+
319
+ return WorkflowInputsDisplay(id=workflow_input_id, name=name, color=color)
319
320
 
320
321
  def _generate_state_value_display(
321
322
  self, state_value: BaseDescriptor, overrides: Optional[StateValueDisplay] = None
@@ -2,10 +2,10 @@ import logging
2
2
  from uuid import UUID
3
3
  from typing import Optional, cast
4
4
 
5
+ from vellum.workflows.constants import undefined
5
6
  from vellum.workflows.nodes.displayable.bases.utils import primitive_to_vellum_value
6
7
  from vellum.workflows.nodes.displayable.final_output_node import FinalOutputNode
7
8
  from vellum.workflows.nodes.utils import get_unadorned_node, get_unadorned_port
8
- from vellum.workflows.references import WorkflowInputReference
9
9
  from vellum.workflows.references.output import OutputReference
10
10
  from vellum.workflows.types.core import JsonArray, JsonObject
11
11
  from vellum.workflows.types.generics import WorkflowType
@@ -15,38 +15,29 @@ from vellum_ee.workflows.display.nodes.base_node_display import BaseNodeDisplay
15
15
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
16
16
  from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
17
17
  from vellum_ee.workflows.display.utils.vellum import infer_vellum_variable_type
18
- from vellum_ee.workflows.display.vellum import WorkflowInputsVellumDisplay, WorkflowInputsVellumDisplayOverrides
19
18
  from vellum_ee.workflows.display.workflows.base_workflow_display import BaseWorkflowDisplay
20
19
 
21
20
  logger = logging.getLogger(__name__)
22
21
 
23
22
 
24
- class VellumWorkflowDisplay(
25
- BaseWorkflowDisplay[
26
- WorkflowType,
27
- WorkflowInputsVellumDisplay,
28
- WorkflowInputsVellumDisplayOverrides,
29
- ]
30
- ):
23
+ class VellumWorkflowDisplay(BaseWorkflowDisplay[WorkflowType]):
31
24
  node_display_base_class = BaseNodeDisplay
32
25
 
33
26
  def serialize(self) -> JsonObject:
34
27
  input_variables: JsonArray = []
35
- for workflow_input, workflow_input_display in self.display_context.workflow_input_displays.items():
36
- default = primitive_to_vellum_value(workflow_input.instance) if workflow_input.instance else None
37
- required = (
38
- workflow_input_display.required
39
- if workflow_input_display.required is not None
40
- else type(None) not in workflow_input.types
28
+ for workflow_input_reference, workflow_input_display in self.display_context.workflow_input_displays.items():
29
+ default = (
30
+ primitive_to_vellum_value(workflow_input_reference.instance)
31
+ if workflow_input_reference.instance
32
+ else None
41
33
  )
42
-
43
34
  input_variables.append(
44
35
  {
45
36
  "id": str(workflow_input_display.id),
46
- "key": workflow_input_display.name or workflow_input.name,
47
- "type": infer_vellum_variable_type(workflow_input),
37
+ "key": workflow_input_display.name or workflow_input_reference.name,
38
+ "type": infer_vellum_variable_type(workflow_input_reference),
48
39
  "default": default.dict() if default else None,
49
- "required": required,
40
+ "required": workflow_input_reference.instance is undefined,
50
41
  "extensions": {"color": workflow_input_display.color},
51
42
  }
52
43
  )
@@ -62,7 +53,7 @@ class VellumWorkflowDisplay(
62
53
  "key": state_value_display.name or state_value_reference.name,
63
54
  "type": infer_vellum_variable_type(state_value_reference),
64
55
  "default": default.dict() if default else None,
65
- "required": state_value_reference.instance is None,
56
+ "required": state_value_reference.instance is undefined,
66
57
  "extensions": {"color": state_value_display.color},
67
58
  }
68
59
  )
@@ -269,20 +260,3 @@ class VellumWorkflowDisplay(
269
260
  "state_variables": state_variables,
270
261
  "output_variables": output_variables,
271
262
  }
272
-
273
- def _generate_workflow_input_display(
274
- self, workflow_input: WorkflowInputReference, overrides: Optional[WorkflowInputsVellumDisplayOverrides] = None
275
- ) -> WorkflowInputsVellumDisplay:
276
- workflow_input_id: UUID
277
- name = None
278
- required = None
279
- color = None
280
- if overrides:
281
- workflow_input_id = overrides.id
282
- name = overrides.name
283
- required = overrides.required
284
- color = overrides.color
285
- else:
286
- workflow_input_id = uuid4_from_hash(f"{self.workflow_id}|inputs|id|{workflow_input.name}")
287
-
288
- return WorkflowInputsVellumDisplay(id=workflow_input_id, name=name, required=required, color=color)