vellum-ai 0.14.16__py3-none-any.whl → 0.14.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.
- vellum/__init__.py +2 -0
- vellum/client/core/client_wrapper.py +1 -1
- vellum/client/types/__init__.py +2 -0
- vellum/client/types/release.py +21 -0
- vellum/client/types/workflow_release_tag_read.py +7 -1
- vellum/prompts/blocks/compilation.py +14 -0
- vellum/types/release.py +3 -0
- vellum/workflows/events/workflow.py +15 -1
- vellum/workflows/nodes/bases/base.py +7 -7
- vellum/workflows/nodes/bases/base_adornment_node.py +2 -0
- vellum/workflows/nodes/core/retry_node/node.py +60 -40
- vellum/workflows/nodes/core/templating_node/node.py +2 -2
- vellum/workflows/nodes/core/try_node/node.py +1 -1
- vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +4 -0
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +27 -1
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/__init__.py +0 -0
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py +298 -0
- vellum/workflows/nodes/displayable/inline_prompt_node/node.py +24 -1
- vellum/workflows/nodes/experimental/openai_chat_completion_node/node.py +7 -1
- vellum/workflows/runner/runner.py +16 -1
- vellum/workflows/utils/tests/test_vellum_variables.py +7 -1
- vellum/workflows/utils/vellum_variables.py +4 -0
- {vellum_ai-0.14.16.dist-info → vellum_ai-0.14.18.dist-info}/METADATA +1 -1
- {vellum_ai-0.14.16.dist-info → vellum_ai-0.14.18.dist-info}/RECORD +39 -34
- vellum_ee/workflows/display/nodes/base_node_display.py +35 -29
- vellum_ee/workflows/display/nodes/get_node_display_class.py +0 -9
- vellum_ee/workflows/display/nodes/vellum/base_adornment_node.py +38 -18
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +6 -0
- vellum_ee/workflows/display/nodes/vellum/templating_node.py +6 -7
- vellum_ee/workflows/display/nodes/vellum/tests/test_templating_node.py +97 -0
- vellum_ee/workflows/display/nodes/vellum/utils.py +1 -1
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py +1 -1
- vellum_ee/workflows/display/vellum.py +1 -148
- vellum_ee/workflows/display/workflows/base_workflow_display.py +1 -1
- vellum_ee/workflows/display/workflows/tests/test_workflow_display.py +61 -17
- vellum_ee/workflows/tests/test_display_meta.py +10 -10
- {vellum_ai-0.14.16.dist-info → vellum_ai-0.14.18.dist-info}/LICENSE +0 -0
- {vellum_ai-0.14.16.dist-info → vellum_ai-0.14.18.dist-info}/WHEEL +0 -0
- {vellum_ai-0.14.16.dist-info → vellum_ai-0.14.18.dist-info}/entry_points.txt +0 -0
@@ -54,7 +54,7 @@ def create_node_input_value_pointer_rules(
|
|
54
54
|
|
55
55
|
if isinstance(value, BaseDescriptor):
|
56
56
|
if isinstance(value, NodeReference):
|
57
|
-
if
|
57
|
+
if value.instance is None:
|
58
58
|
raise ValueError(f"Expected NodeReference {value.name} to have an instance")
|
59
59
|
value = cast(BaseDescriptor, value.instance)
|
60
60
|
|
@@ -1,11 +1,10 @@
|
|
1
1
|
from dataclasses import dataclass, field
|
2
|
-
from enum import Enum
|
3
2
|
from uuid import UUID
|
4
3
|
from typing import List, Literal, Optional, Union
|
5
4
|
|
6
5
|
from pydantic import Field
|
7
6
|
|
8
|
-
from vellum import
|
7
|
+
from vellum import VellumVariableType
|
9
8
|
from vellum.client.types.array_vellum_value import ArrayVellumValue
|
10
9
|
from vellum.client.types.vellum_value import VellumValue
|
11
10
|
from vellum.core import UniversalBaseModel
|
@@ -138,24 +137,6 @@ class WorkflowOutputVellumDisplay(WorkflowOutputVellumDisplayOverrides):
|
|
138
137
|
pass
|
139
138
|
|
140
139
|
|
141
|
-
class WorkflowNodeType(str, Enum):
|
142
|
-
PROMPT = "PROMPT"
|
143
|
-
TEMPLATING = "TEMPLATING"
|
144
|
-
NOTE = "NOTE"
|
145
|
-
CODE_EXECUTION = "CODE_EXECUTION"
|
146
|
-
METRIC = "METRIC"
|
147
|
-
SEARCH = "SEARCH"
|
148
|
-
WEBHOOK = "WEBHOOK"
|
149
|
-
MERGE = "MERGE"
|
150
|
-
CONDITIONAL = "CONDITIONAL"
|
151
|
-
API = "API"
|
152
|
-
ENTRYPOINT = "ENTRYPOINT"
|
153
|
-
TERMINAL = "TERMINAL"
|
154
|
-
SUBWORKFLOW = "SUBWORKFLOW"
|
155
|
-
MAP = "MAP"
|
156
|
-
ERROR = "ERROR"
|
157
|
-
|
158
|
-
|
159
140
|
class ConstantValuePointer(UniversalBaseModel):
|
160
141
|
type: Literal["CONSTANT_VALUE"] = "CONSTANT_VALUE"
|
161
142
|
data: VellumValue
|
@@ -220,131 +201,3 @@ class NodeInput(UniversalBaseModel):
|
|
220
201
|
id: str
|
221
202
|
key: str
|
222
203
|
value: NodeInputValuePointer
|
223
|
-
|
224
|
-
|
225
|
-
class BaseWorkflowNode(UniversalBaseModel):
|
226
|
-
id: str
|
227
|
-
inputs: List[NodeInput]
|
228
|
-
type: str
|
229
|
-
display_data: Optional[NodeDisplayData] = None
|
230
|
-
base: CodeResourceDefinition
|
231
|
-
definition: CodeResourceDefinition
|
232
|
-
|
233
|
-
|
234
|
-
class EntrypointNodeData(UniversalBaseModel):
|
235
|
-
source_handle_id: str
|
236
|
-
|
237
|
-
|
238
|
-
class EntrypointNode(BaseWorkflowNode):
|
239
|
-
type: Literal[WorkflowNodeType.ENTRYPOINT] = WorkflowNodeType.ENTRYPOINT
|
240
|
-
data: EntrypointNodeData
|
241
|
-
|
242
|
-
|
243
|
-
class PromptTemplateBlockData(UniversalBaseModel):
|
244
|
-
version: Literal[1] = 1
|
245
|
-
# blocks: List[PromptBlockRequest]
|
246
|
-
|
247
|
-
|
248
|
-
class PromptVersionExecConfig(UniversalBaseModel):
|
249
|
-
parameters: PromptParameters
|
250
|
-
input_variables: List[VellumVariable]
|
251
|
-
prompt_template_block_data: PromptTemplateBlockData
|
252
|
-
|
253
|
-
|
254
|
-
class BasePromptNodeData(UniversalBaseModel):
|
255
|
-
label: str
|
256
|
-
output_id: str
|
257
|
-
error_output_id: Optional[str] = None
|
258
|
-
array_output_id: str
|
259
|
-
source_handle_id: str
|
260
|
-
target_handle_id: str
|
261
|
-
|
262
|
-
|
263
|
-
class InlinePromptNodeData(BasePromptNodeData):
|
264
|
-
variant: Literal["INLINE"] = "INLINE"
|
265
|
-
exec_config: PromptVersionExecConfig
|
266
|
-
ml_model_name: str
|
267
|
-
|
268
|
-
|
269
|
-
class DeploymentPromptNodeData(BasePromptNodeData):
|
270
|
-
variant: Literal["DEPLOYMENT"] = "DEPLOYMENT"
|
271
|
-
deployment_id: str
|
272
|
-
release_tag: str
|
273
|
-
|
274
|
-
|
275
|
-
PromptNodeData = Union[
|
276
|
-
InlinePromptNodeData,
|
277
|
-
DeploymentPromptNodeData,
|
278
|
-
]
|
279
|
-
|
280
|
-
|
281
|
-
class PromptNode(BaseWorkflowNode):
|
282
|
-
type: Literal[WorkflowNodeType.PROMPT] = WorkflowNodeType.PROMPT
|
283
|
-
data: PromptNodeData
|
284
|
-
|
285
|
-
|
286
|
-
class SearchNodeData(UniversalBaseModel):
|
287
|
-
label: str
|
288
|
-
|
289
|
-
results_output_id: str
|
290
|
-
text_output_id: str
|
291
|
-
error_output_id: Optional[str] = None
|
292
|
-
|
293
|
-
source_handle_id: str
|
294
|
-
target_handle_id: str
|
295
|
-
|
296
|
-
query_node_input_id: str
|
297
|
-
document_index_node_input_id: str
|
298
|
-
weights_node_input_id: str
|
299
|
-
limit_node_input_id: str
|
300
|
-
separator_node_input_id: str
|
301
|
-
result_merging_enabled_node_input_id: str
|
302
|
-
external_id_filters_node_input_id: str
|
303
|
-
metadata_filters_node_input_id: str
|
304
|
-
|
305
|
-
|
306
|
-
class SearchNode(BaseWorkflowNode):
|
307
|
-
type: Literal[WorkflowNodeType.SEARCH] = WorkflowNodeType.SEARCH
|
308
|
-
data: SearchNodeData
|
309
|
-
|
310
|
-
|
311
|
-
class FinalOutputNodeData(UniversalBaseModel):
|
312
|
-
label: str
|
313
|
-
name: str
|
314
|
-
target_handle_id: str
|
315
|
-
output_id: str
|
316
|
-
output_type: VellumVariableType
|
317
|
-
node_input_id: str
|
318
|
-
|
319
|
-
|
320
|
-
class FinalOutputNode(BaseWorkflowNode):
|
321
|
-
type: Literal[WorkflowNodeType.TERMINAL] = WorkflowNodeType.TERMINAL
|
322
|
-
data: FinalOutputNodeData
|
323
|
-
|
324
|
-
|
325
|
-
WorkflowNode = Union[
|
326
|
-
EntrypointNode,
|
327
|
-
PromptNode,
|
328
|
-
SearchNode,
|
329
|
-
FinalOutputNode,
|
330
|
-
]
|
331
|
-
|
332
|
-
|
333
|
-
class WorkflowEdge(UniversalBaseModel):
|
334
|
-
id: str
|
335
|
-
source_node_id: str
|
336
|
-
source_handle_id: str
|
337
|
-
target_node_id: str
|
338
|
-
target_handle_id: str
|
339
|
-
|
340
|
-
|
341
|
-
class WorkflowRawData(UniversalBaseModel):
|
342
|
-
nodes: List[WorkflowNode]
|
343
|
-
edges: List[WorkflowEdge]
|
344
|
-
display_data: Optional[WorkflowDisplayData] = None
|
345
|
-
|
346
|
-
|
347
|
-
class WorkflowVersionExecConfig(UniversalBaseModel):
|
348
|
-
workflow_raw_data: WorkflowRawData
|
349
|
-
input_variables: List[VellumVariable]
|
350
|
-
output_variables: List[VellumVariable]
|
@@ -429,7 +429,7 @@ class BaseWorkflowDisplay(
|
|
429
429
|
)
|
430
430
|
subworkflow_display_context = subworkflow_display.get_event_display_context()
|
431
431
|
|
432
|
-
node_event_displays[
|
432
|
+
node_event_displays[node_id] = NodeEventDisplayContext(
|
433
433
|
input_display=input_display,
|
434
434
|
output_display=output_display,
|
435
435
|
port_display=port_display_meta,
|
@@ -5,9 +5,11 @@ from vellum.workflows.nodes.bases.base import BaseNode
|
|
5
5
|
from vellum.workflows.nodes.core.inline_subworkflow_node.node import InlineSubworkflowNode
|
6
6
|
from vellum.workflows.nodes.core.retry_node.node import RetryNode
|
7
7
|
from vellum.workflows.nodes.core.templating_node.node import TemplatingNode
|
8
|
+
from vellum.workflows.nodes.core.try_node.node import TryNode
|
8
9
|
from vellum.workflows.workflows.base import BaseWorkflow
|
9
10
|
from vellum_ee.workflows.display.nodes import BaseNodeDisplay
|
10
11
|
from vellum_ee.workflows.display.nodes.vellum.retry_node import BaseRetryNodeDisplay
|
12
|
+
from vellum_ee.workflows.display.nodes.vellum.try_node import BaseTryNodeDisplay
|
11
13
|
from vellum_ee.workflows.display.vellum import NodeDisplayData, NodeDisplayPosition
|
12
14
|
from vellum_ee.workflows.display.workflows import VellumWorkflowDisplay
|
13
15
|
from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
|
@@ -112,13 +114,36 @@ def test_get_event_display_context__node_display_filled_without_base_display():
|
|
112
114
|
display_context = VellumWorkflowDisplay(MyWorkflow).get_event_display_context()
|
113
115
|
|
114
116
|
# THEN the node display should be included
|
115
|
-
assert
|
116
|
-
node_event_display = display_context.node_displays[
|
117
|
+
assert StartNode.__id__ in display_context.node_displays
|
118
|
+
node_event_display = display_context.node_displays[StartNode.__id__]
|
117
119
|
|
118
120
|
# AND so should their output ids
|
119
121
|
assert StartNode.__output_ids__ == node_event_display.output_display
|
120
122
|
|
121
123
|
|
124
|
+
def test_get_event_display_context__node_display_filled_without_output_display():
|
125
|
+
# GIVEN a simple workflow
|
126
|
+
class StartNode(BaseNode):
|
127
|
+
class Outputs(BaseNode.Outputs):
|
128
|
+
foo: str
|
129
|
+
|
130
|
+
class MyWorkflow(BaseWorkflow):
|
131
|
+
graph = StartNode
|
132
|
+
|
133
|
+
class StartNodeDisplay(BaseNodeDisplay[StartNode]):
|
134
|
+
pass
|
135
|
+
|
136
|
+
# WHEN we gather the event display context
|
137
|
+
display_context = VellumWorkflowDisplay(MyWorkflow).get_event_display_context()
|
138
|
+
|
139
|
+
# THEN the node display should be included
|
140
|
+
assert StartNode.__id__ in display_context.node_displays
|
141
|
+
node_event_display = display_context.node_displays[StartNode.__id__]
|
142
|
+
|
143
|
+
# AND so should their output ids
|
144
|
+
assert node_event_display.output_display.keys() == {"foo"}
|
145
|
+
|
146
|
+
|
122
147
|
def test_get_event_display_context__node_display_to_include_subworkflow_display():
|
123
148
|
# GIVEN a simple workflow
|
124
149
|
class InnerNode(BaseNode):
|
@@ -138,26 +163,40 @@ def test_get_event_display_context__node_display_to_include_subworkflow_display(
|
|
138
163
|
display_context = VellumWorkflowDisplay(MyWorkflow).get_event_display_context()
|
139
164
|
|
140
165
|
# THEN the subworkflow display should be included
|
141
|
-
assert
|
142
|
-
node_event_display = display_context.node_displays[
|
166
|
+
assert SubworkflowNode.__id__ in display_context.node_displays
|
167
|
+
node_event_display = display_context.node_displays[SubworkflowNode.__id__]
|
143
168
|
|
144
169
|
assert node_event_display.subworkflow_display is not None
|
145
|
-
assert
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
170
|
+
assert InnerNode.__id__ in node_event_display.subworkflow_display.node_displays
|
171
|
+
|
172
|
+
|
173
|
+
@pytest.mark.parametrize(
|
174
|
+
["AdornmentNode", "AdornmentNodeDisplay", "expected_adornment_output_names"],
|
175
|
+
[
|
176
|
+
[RetryNode, BaseRetryNodeDisplay, {"foo"}],
|
177
|
+
[TryNode, BaseTryNodeDisplay, {"foo", "error"}],
|
178
|
+
],
|
179
|
+
ids=["retry_node", "try_node"],
|
180
|
+
)
|
181
|
+
def test_get_event_display_context__node_display_for_adornment_nodes(
|
182
|
+
AdornmentNode,
|
183
|
+
AdornmentNodeDisplay,
|
184
|
+
expected_adornment_output_names,
|
185
|
+
):
|
186
|
+
# GIVEN a simple workflow with an adornment
|
187
|
+
@AdornmentNode.wrap()
|
151
188
|
class MyNode(BaseNode):
|
152
|
-
|
189
|
+
class Outputs(BaseNode.Outputs):
|
190
|
+
foo: str
|
153
191
|
|
154
192
|
class MyWorkflow(BaseWorkflow):
|
155
193
|
graph = MyNode
|
156
194
|
|
157
195
|
# AND a display class for the node
|
196
|
+
adornment_node_id = uuid4()
|
158
197
|
inner_node_id = uuid4()
|
159
198
|
|
160
|
-
@
|
199
|
+
@AdornmentNodeDisplay.wrap(node_id=adornment_node_id)
|
161
200
|
class MyNodeDisplay(BaseNodeDisplay[MyNode]):
|
162
201
|
node_id = inner_node_id
|
163
202
|
|
@@ -165,10 +204,15 @@ def test_get_event_display_context__node_display_for_adornment_nodes():
|
|
165
204
|
display_context = VellumWorkflowDisplay(MyWorkflow).get_event_display_context()
|
166
205
|
|
167
206
|
# THEN the subworkflow display should be included
|
168
|
-
assert
|
169
|
-
node_event_display = display_context.node_displays[
|
207
|
+
assert adornment_node_id in display_context.node_displays
|
208
|
+
node_event_display = display_context.node_displays[adornment_node_id]
|
170
209
|
assert node_event_display.subworkflow_display is not None
|
171
|
-
assert
|
210
|
+
assert inner_node_id in node_event_display.subworkflow_display.node_displays
|
211
|
+
|
212
|
+
# AND the inner node should have the correct outputs
|
213
|
+
inner_node_display = node_event_display.subworkflow_display.node_displays[inner_node_id]
|
214
|
+
assert inner_node_display.output_display.keys() == {"foo"}
|
215
|
+
assert node_event_display.output_display.keys() == expected_adornment_output_names
|
172
216
|
|
173
217
|
|
174
218
|
def test_get_event_display_context__templating_node_input_display():
|
@@ -187,7 +231,7 @@ def test_get_event_display_context__templating_node_input_display():
|
|
187
231
|
display_context = VellumWorkflowDisplay(MyWorkflow).get_event_display_context()
|
188
232
|
|
189
233
|
# THEN the subworkflow display should be included
|
190
|
-
assert
|
191
|
-
node_event_display = display_context.node_displays[
|
234
|
+
assert MyNode.__id__ in display_context.node_displays
|
235
|
+
node_event_display = display_context.node_displays[MyNode.__id__]
|
192
236
|
|
193
237
|
assert node_event_display.input_display.keys() == {"inputs.foo"}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import pytest
|
2
2
|
import os
|
3
3
|
import sys
|
4
|
-
from uuid import
|
4
|
+
from uuid import uuid4
|
5
5
|
|
6
6
|
from vellum.workflows import BaseWorkflow
|
7
7
|
from vellum_ee.workflows.display.workflows import BaseWorkflowDisplay
|
@@ -35,22 +35,22 @@ def test_base_class_dynamic_import(files):
|
|
35
35
|
"node_displays": {
|
36
36
|
"533c6bd8-6088-4abc-a168-8c1758abcd33": {
|
37
37
|
"input_display": {
|
38
|
-
"example_var_1":
|
39
|
-
"template":
|
38
|
+
"example_var_1": "a0d1d7cf-242a-4bd9-a437-d308a7ced9b3",
|
39
|
+
"template": "f97d721a-e685-498e-90c3-9c3d9358fdad",
|
40
40
|
},
|
41
|
-
"output_display": {"result":
|
42
|
-
"port_display": {"default":
|
41
|
+
"output_display": {"result": "423bc529-1a1a-4f72-af4d-cbdb5f0a5929"},
|
42
|
+
"port_display": {"default": "afda9a19-0618-42e1-9b63-5d0db2a88f62"},
|
43
43
|
"subworkflow_display": None,
|
44
44
|
},
|
45
45
|
"f3ef4b2b-fec9-4026-9cc6-e5eac295307f": {
|
46
|
-
"input_display": {"node_input":
|
47
|
-
"output_display": {"value":
|
46
|
+
"input_display": {"node_input": "fe6cba85-2423-4b5e-8f85-06311a8be5fb"},
|
47
|
+
"output_display": {"value": "5469b810-6ea6-4362-9e79-e360d44a1405"},
|
48
48
|
"port_display": {},
|
49
49
|
"subworkflow_display": None,
|
50
50
|
},
|
51
51
|
},
|
52
|
-
"workflow_inputs": {"input_value":
|
53
|
-
"workflow_outputs": {"final_output":
|
52
|
+
"workflow_inputs": {"input_value": "2268a996-bd17-4832-b3ff-f5662d54b306"},
|
53
|
+
"workflow_outputs": {"final_output": "5469b810-6ea6-4362-9e79-e360d44a1405"},
|
54
54
|
}
|
55
55
|
assert display_meta
|
56
|
-
assert display_meta.
|
56
|
+
assert display_meta.model_dump(mode="json") == expected_result
|
File without changes
|
File without changes
|
File without changes
|