vellum-ai 0.11.0__py3-none-any.whl → 0.11.1__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 (43) hide show
  1. vellum/__init__.py +16 -0
  2. vellum/client/core/client_wrapper.py +1 -1
  3. vellum/client/types/__init__.py +28 -0
  4. vellum/client/types/test_suite_run_exec_config.py +7 -1
  5. vellum/client/types/test_suite_run_exec_config_request.py +8 -0
  6. vellum/client/types/test_suite_run_prompt_sandbox_history_item_exec_config.py +31 -0
  7. vellum/client/types/test_suite_run_prompt_sandbox_history_item_exec_config_data.py +27 -0
  8. vellum/client/types/test_suite_run_prompt_sandbox_history_item_exec_config_data_request.py +27 -0
  9. vellum/client/types/test_suite_run_prompt_sandbox_history_item_exec_config_request.py +31 -0
  10. vellum/client/types/test_suite_run_workflow_sandbox_history_item_exec_config.py +31 -0
  11. vellum/client/types/test_suite_run_workflow_sandbox_history_item_exec_config_data.py +27 -0
  12. vellum/client/types/test_suite_run_workflow_sandbox_history_item_exec_config_data_request.py +27 -0
  13. vellum/client/types/test_suite_run_workflow_sandbox_history_item_exec_config_request.py +31 -0
  14. vellum/types/test_suite_run_prompt_sandbox_history_item_exec_config.py +3 -0
  15. vellum/types/test_suite_run_prompt_sandbox_history_item_exec_config_data.py +3 -0
  16. vellum/types/test_suite_run_prompt_sandbox_history_item_exec_config_data_request.py +3 -0
  17. vellum/types/test_suite_run_prompt_sandbox_history_item_exec_config_request.py +3 -0
  18. vellum/types/test_suite_run_workflow_sandbox_history_item_exec_config.py +3 -0
  19. vellum/types/test_suite_run_workflow_sandbox_history_item_exec_config_data.py +3 -0
  20. vellum/types/test_suite_run_workflow_sandbox_history_item_exec_config_data_request.py +3 -0
  21. vellum/types/test_suite_run_workflow_sandbox_history_item_exec_config_request.py +3 -0
  22. vellum/workflows/context.py +42 -0
  23. vellum/workflows/nodes/core/inline_subworkflow_node/node.py +13 -7
  24. vellum/workflows/nodes/displayable/api_node/node.py +3 -2
  25. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +9 -0
  26. vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +10 -1
  27. vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +10 -1
  28. vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +1 -1
  29. vellum/workflows/runner/runner.py +74 -70
  30. vellum/workflows/workflows/event_filters.py +4 -1
  31. {vellum_ai-0.11.0.dist-info → vellum_ai-0.11.1.dist-info}/METADATA +1 -1
  32. {vellum_ai-0.11.0.dist-info → vellum_ai-0.11.1.dist-info}/RECORD +43 -26
  33. vellum_cli/pull.py +3 -1
  34. vellum_cli/tests/test_pull.py +18 -0
  35. vellum_ee/workflows/display/base.py +1 -0
  36. vellum_ee/workflows/display/nodes/vellum/api_node.py +53 -54
  37. vellum_ee/workflows/display/nodes/vellum/utils.py +26 -6
  38. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +29 -1
  39. vellum_ee/workflows/display/vellum.py +1 -1
  40. vellum_ee/workflows/display/workflows/vellum_workflow_display.py +10 -7
  41. {vellum_ai-0.11.0.dist-info → vellum_ai-0.11.1.dist-info}/LICENSE +0 -0
  42. {vellum_ai-0.11.0.dist-info → vellum_ai-0.11.1.dist-info}/WHEEL +0 -0
  43. {vellum_ai-0.11.0.dist-info → vellum_ai-0.11.1.dist-info}/entry_points.txt +0 -0
@@ -8,6 +8,7 @@ from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeV
8
8
  from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
9
9
  from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
10
10
  from vellum_ee.workflows.display.types import WorkflowDisplayContext
11
+ from vellum_ee.workflows.display.vellum import WorkspaceSecretPointer
11
12
 
12
13
  _APINodeType = TypeVar("_APINodeType", bound=APINode)
13
14
 
@@ -79,16 +80,13 @@ class BaseAPINodeDisplay(BaseNodeVellumDisplay[_APINodeType], Generic[_APINodeTy
79
80
  if authorization_type
80
81
  else None
81
82
  )
82
- bearer_token_value_node_input = (
83
- create_node_input(
84
- node_id=node_id,
85
- input_name="bearer_token_value",
86
- value=bearer_token_value,
87
- display_context=display_context,
88
- input_id=self.bearer_token_value_input_id,
89
- )
90
- if bearer_token_value
91
- else None
83
+ bearer_token_value_node_input = create_node_input(
84
+ node_id=node_id,
85
+ input_name="bearer_token_value",
86
+ value=bearer_token_value,
87
+ display_context=display_context,
88
+ input_id=self.bearer_token_value_input_id,
89
+ pointer_type=WorkspaceSecretPointer,
92
90
  )
93
91
  api_key_header_key_node_input = (
94
92
  create_node_input(
@@ -101,52 +99,52 @@ class BaseAPINodeDisplay(BaseNodeVellumDisplay[_APINodeType], Generic[_APINodeTy
101
99
  if api_key_header_key
102
100
  else None
103
101
  )
104
- api_key_header_value_node_input = (
105
- create_node_input(
106
- node_id=node_id,
107
- input_name="api_key_header_value",
108
- value=node.api_key_header_value,
109
- display_context=display_context,
110
- input_id=self.api_key_header_value_input_id,
111
- )
112
- if headers and api_key_header_key and api_key_header_value
113
- else None
102
+ api_key_header_value_node_input = create_node_input(
103
+ node_id=node_id,
104
+ input_name="api_key_header_value",
105
+ value=api_key_header_value,
106
+ display_context=display_context,
107
+ input_id=self.api_key_header_value_input_id,
108
+ pointer_type=WorkspaceSecretPointer,
114
109
  )
115
110
 
116
- # TODO: Add stable IDs for additional headers
117
- # https://app.shortcut.com/vellum/story/5083
118
- additional_headers: JsonArray = (
119
- [
120
- {
121
- "header_key_input_id": create_node_input(
122
- node_id=node_id,
123
- input_name="additional_header_key",
124
- value=key,
125
- display_context=display_context,
126
- input_id=(
127
- self.additional_header_key_input_ids.get(key)
128
- if self.additional_header_key_input_ids
129
- else None
130
- ),
131
- ).id,
132
- "header_value_input_id": create_node_input(
133
- node_id=node_id,
134
- input_name="additional_header_value",
135
- value=value,
136
- display_context=display_context,
137
- input_id=(
138
- self.additional_header_value_input_ids.get(key)
139
- if self.additional_header_value_input_ids
140
- else None
141
- ),
142
- ).id,
143
- }
144
- for key, value in headers.items()
145
- if key not in {api_key_header_key, "Authorization"}
146
- ]
147
- if headers
148
- else []
149
- )
111
+ additional_header_inputs = []
112
+
113
+ additional_headers: JsonArray = []
114
+ if headers:
115
+ for key, value in headers.items():
116
+ if key in {api_key_header_key, "Authorization"}:
117
+ continue
118
+
119
+ header_key_input = create_node_input(
120
+ node_id=node_id,
121
+ input_name="additional_header_key",
122
+ value=key,
123
+ display_context=display_context,
124
+ input_id=(
125
+ self.additional_header_key_input_ids.get(key) if self.additional_header_key_input_ids else None
126
+ ),
127
+ )
128
+ header_value_input = create_node_input(
129
+ node_id=node_id,
130
+ input_name="additional_header_value",
131
+ value=value,
132
+ display_context=display_context,
133
+ input_id=(
134
+ self.additional_header_value_input_ids.get(key)
135
+ if self.additional_header_value_input_ids
136
+ else None
137
+ ),
138
+ )
139
+
140
+ additional_header_inputs.extend([header_key_input, header_value_input])
141
+
142
+ additional_headers.append(
143
+ {
144
+ "header_key_input_id": header_key_input.id,
145
+ "header_value_input_id": header_value_input.id,
146
+ }
147
+ )
150
148
 
151
149
  inputs = [
152
150
  input
@@ -161,6 +159,7 @@ class BaseAPINodeDisplay(BaseNodeVellumDisplay[_APINodeType], Generic[_APINodeTy
161
159
  ]
162
160
  if input is not None
163
161
  ]
162
+ inputs.extend(additional_header_inputs)
164
163
 
165
164
  _, text_output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.text)]
166
165
  _, json_output_display = display_context.node_output_displays[cast(OutputReference, node.Outputs.json)]
@@ -1,5 +1,5 @@
1
1
  from uuid import UUID
2
- from typing import Any, List, Optional, cast
2
+ from typing import Any, List, Optional, Type, cast
3
3
 
4
4
  from vellum.workflows.descriptors.base import BaseDescriptor
5
5
  from vellum.workflows.expressions.coalesce_expression import CoalesceExpression
@@ -13,6 +13,8 @@ from vellum_ee.workflows.display.vellum import (
13
13
  NodeInput,
14
14
  NodeInputValuePointer,
15
15
  NodeInputValuePointerRule,
16
+ WorkspaceSecretData,
17
+ WorkspaceSecretPointer,
16
18
  )
17
19
 
18
20
 
@@ -22,6 +24,7 @@ def create_node_input(
22
24
  value: Any,
23
25
  display_context: WorkflowDisplayContext,
24
26
  input_id: Optional[UUID],
27
+ pointer_type: Optional[Type[NodeInputValuePointerRule]] = ConstantValuePointer,
25
28
  ) -> NodeInput:
26
29
  input_id = input_id or uuid4_from_hash(f"{node_id}|{input_name}")
27
30
  if (
@@ -33,7 +36,7 @@ def create_node_input(
33
36
  if wrapped_node._is_wrapped_node:
34
37
  value = getattr(wrapped_node.Outputs, value.name)
35
38
 
36
- rules = create_node_input_value_pointer_rules(value, display_context)
39
+ rules = create_node_input_value_pointer_rules(value, display_context, pointer_type=pointer_type)
37
40
  return NodeInput(
38
41
  id=str(input_id),
39
42
  key=input_name,
@@ -48,6 +51,7 @@ def create_node_input_value_pointer_rules(
48
51
  value: Any,
49
52
  display_context: WorkflowDisplayContext,
50
53
  existing_rules: Optional[List[NodeInputValuePointerRule]] = None,
54
+ pointer_type: Optional[Type[NodeInputValuePointerRule]] = None,
51
55
  ) -> List[NodeInputValuePointerRule]:
52
56
  node_input_value_pointer_rules: List[NodeInputValuePointerRule] = existing_rules or []
53
57
 
@@ -59,18 +63,34 @@ def create_node_input_value_pointer_rules(
59
63
 
60
64
  if isinstance(value, CoalesceExpression):
61
65
  # Recursively handle the left-hand side
62
- lhs_rules = create_node_input_value_pointer_rules(value.lhs, display_context, [])
66
+ lhs_rules = create_node_input_value_pointer_rules(value.lhs, display_context, [], pointer_type=pointer_type)
63
67
  node_input_value_pointer_rules.extend(lhs_rules)
64
68
 
65
69
  # Handle the right-hand side
66
70
  if not isinstance(value.rhs, CoalesceExpression):
67
- rhs_rules = create_node_input_value_pointer_rules(value.rhs, display_context, [])
71
+ rhs_rules = create_node_input_value_pointer_rules(
72
+ value.rhs, display_context, [], pointer_type=pointer_type
73
+ )
68
74
  node_input_value_pointer_rules.extend(rhs_rules)
69
75
  else:
70
76
  # Non-CoalesceExpression case
71
77
  node_input_value_pointer_rules.append(create_node_input_value_pointer_rule(value, display_context))
72
78
  else:
73
- vellum_variable_value = primitive_to_vellum_value(value)
74
- node_input_value_pointer_rules.append(ConstantValuePointer(type="CONSTANT_VALUE", data=vellum_variable_value))
79
+ pointer = create_pointer(value, pointer_type)
80
+ node_input_value_pointer_rules.append(pointer)
75
81
 
76
82
  return node_input_value_pointer_rules
83
+
84
+
85
+ def create_pointer(
86
+ value: Any,
87
+ pointer_type: Optional[Type[NodeInputValuePointerRule]] = None,
88
+ ) -> NodeInputValuePointerRule:
89
+ if value is None:
90
+ if pointer_type is WorkspaceSecretPointer:
91
+ return WorkspaceSecretPointer(
92
+ type="WORKSPACE_SECRET", data=WorkspaceSecretData(type="STRING", workspace_secret_id=None)
93
+ )
94
+
95
+ vellum_variable_value = primitive_to_vellum_value(value)
96
+ return ConstantValuePointer(type="CONSTANT_VALUE", data=vellum_variable_value)
@@ -119,6 +119,16 @@ def test_serialize_workflow(vellum_client):
119
119
  "combinator": "OR",
120
120
  },
121
121
  },
122
+ {
123
+ "id": "fee5e3c9-442a-4922-ba80-5ee07361cea7",
124
+ "key": "bearer_token_value",
125
+ "value": {
126
+ "rules": [
127
+ {"type": "WORKSPACE_SECRET", "data": {"type": "STRING", "workspace_secret_id": None}}
128
+ ],
129
+ "combinator": "OR",
130
+ },
131
+ },
122
132
  {
123
133
  "id": "2fcdfbc3-8095-4277-bb4a-a201fd326b54",
124
134
  "key": "api_key_header_key",
@@ -143,6 +153,24 @@ def test_serialize_workflow(vellum_client):
143
153
  "combinator": "OR",
144
154
  },
145
155
  },
156
+ {
157
+ "id": "57c31247-998a-430d-bb62-bf50eca7df35",
158
+ "key": "additional_header_key",
159
+ "value": {
160
+ "rules": [{"type": "CONSTANT_VALUE", "data": {"type": "STRING", "value": "additional_header"}}],
161
+ "combinator": "OR",
162
+ },
163
+ },
164
+ {
165
+ "id": "47b32274-f19b-4c15-b788-55c069c311c5",
166
+ "key": "additional_header_value",
167
+ "value": {
168
+ "rules": [
169
+ {"type": "CONSTANT_VALUE", "data": {"type": "STRING", "value": "additional header value"}}
170
+ ],
171
+ "combinator": "OR",
172
+ },
173
+ },
146
174
  ],
147
175
  "data": {
148
176
  "label": "Simple A P I Node",
@@ -153,7 +181,7 @@ def test_serialize_workflow(vellum_client):
153
181
  "method_input_id": "fd61b5ac-39f9-4cfe-a839-f8ce78c202df",
154
182
  "body_input_id": "c3a17ceb-e201-4025-b18a-9162aac7705e",
155
183
  "authorization_type_input_id": "3092bf23-3202-4f3e-874c-9a33ccc73459",
156
- "bearer_token_value_input_id": None,
184
+ "bearer_token_value_input_id": "fee5e3c9-442a-4922-ba80-5ee07361cea7",
157
185
  "api_key_header_key_input_id": "2fcdfbc3-8095-4277-bb4a-a201fd326b54",
158
186
  "api_key_header_value_input_id": "d794bb51-a419-4fd8-be63-dfaf4166e831",
159
187
  "additional_headers": [
@@ -202,7 +202,7 @@ class InputVariablePointer(UniversalBaseModel):
202
202
 
203
203
  class WorkspaceSecretData(UniversalBaseModel):
204
204
  type: VellumVariableType
205
- workspace_secret_id: str
205
+ workspace_secret_id: Optional[str] = None
206
206
 
207
207
 
208
208
  class WorkspaceSecretPointer(UniversalBaseModel):
@@ -14,7 +14,6 @@ from vellum.workflows.types.core import JsonArray, JsonObject
14
14
  from vellum.workflows.types.generics import WorkflowType
15
15
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
16
16
  from vellum_ee.workflows.display.nodes.types import PortDisplay
17
- from vellum_ee.workflows.display.nodes.utils import raise_if_descriptor
18
17
  from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input
19
18
  from vellum_ee.workflows.display.utils.uuids import uuid4_from_hash
20
19
  from vellum_ee.workflows.display.utils.vellum import infer_vellum_variable_type, primitive_to_vellum_value
@@ -57,12 +56,12 @@ class VellumWorkflowDisplay(
57
56
  def serialize(self, raise_errors: bool = True) -> JsonObject:
58
57
  input_variables: JsonArray = []
59
58
  for workflow_input, workflow_input_display in self.display_context.workflow_input_displays.items():
60
- default = (
61
- primitive_to_vellum_value(raise_if_descriptor(workflow_input.instance))
62
- if workflow_input.instance
63
- else None
59
+ default = primitive_to_vellum_value(workflow_input.instance) if workflow_input.instance else None
60
+ required = (
61
+ workflow_input_display.required
62
+ if workflow_input_display.required is not None
63
+ else type(None) not in workflow_input.types
64
64
  )
65
- required = type(None) not in workflow_input.types
66
65
 
67
66
  input_variables.append(
68
67
  {
@@ -270,12 +269,16 @@ class VellumWorkflowDisplay(
270
269
  self, workflow_input: WorkflowInputReference, overrides: Optional[WorkflowInputsVellumDisplayOverrides] = None
271
270
  ) -> WorkflowInputsVellumDisplay:
272
271
  workflow_input_id: UUID
272
+ required = None
273
+ color = None
273
274
  if overrides:
274
275
  workflow_input_id = overrides.id
276
+ required = overrides.required
277
+ color = overrides.color
275
278
  else:
276
279
  workflow_input_id = uuid4_from_hash(f"{self.workflow_id}|inputs|id|{workflow_input.name}")
277
280
 
278
- return WorkflowInputsVellumDisplay(id=workflow_input_id)
281
+ return WorkflowInputsVellumDisplay(id=workflow_input_id, required=required, color=color)
279
282
 
280
283
  def _generate_entrypoint_display(
281
284
  self,