vellum-ai 1.2.3__py3-none-any.whl → 1.2.4__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 +2 -2
- vellum/workflows/events/tests/test_event.py +9 -0
- vellum/workflows/events/types.py +3 -1
- vellum/workflows/integrations/tests/test_mcp_service.py +40 -1
- vellum/workflows/nodes/core/templating_node/node.py +3 -2
- vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py +129 -0
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +12 -0
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py +41 -0
- vellum/workflows/nodes/displayable/bases/utils.py +38 -1
- vellum/workflows/nodes/displayable/code_execution_node/utils.py +3 -20
- vellum/workflows/nodes/displayable/inline_prompt_node/node.py +3 -26
- vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +3 -25
- vellum/workflows/nodes/utils.py +26 -1
- vellum/workflows/types/definition.py +1 -0
- vellum/workflows/utils/functions.py +4 -0
- vellum/workflows/utils/tests/test_functions.py +6 -3
- {vellum_ai-1.2.3.dist-info → vellum_ai-1.2.4.dist-info}/METADATA +1 -1
- {vellum_ai-1.2.3.dist-info → vellum_ai-1.2.4.dist-info}/RECORD +28 -28
- vellum_cli/__init__.py +6 -0
- vellum_cli/config.py +2 -0
- vellum_cli/push.py +3 -0
- vellum_cli/tests/test_pull.py +2 -0
- vellum_cli/tests/test_push.py +39 -0
- vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py +2 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_mcp_serialization.py +1 -0
- {vellum_ai-1.2.3.dist-info → vellum_ai-1.2.4.dist-info}/LICENSE +0 -0
- {vellum_ai-1.2.3.dist-info → vellum_ai-1.2.4.dist-info}/WHEEL +0 -0
- {vellum_ai-1.2.3.dist-info → vellum_ai-1.2.4.dist-info}/entry_points.txt +0 -0
@@ -27,10 +27,10 @@ class BaseClientWrapper:
|
|
27
27
|
|
28
28
|
def get_headers(self) -> typing.Dict[str, str]:
|
29
29
|
headers: typing.Dict[str, str] = {
|
30
|
-
"User-Agent": "vellum-ai/1.2.
|
30
|
+
"User-Agent": "vellum-ai/1.2.4",
|
31
31
|
"X-Fern-Language": "Python",
|
32
32
|
"X-Fern-SDK-Name": "vellum-ai",
|
33
|
-
"X-Fern-SDK-Version": "1.2.
|
33
|
+
"X-Fern-SDK-Version": "1.2.4",
|
34
34
|
**(self.get_custom_headers() or {}),
|
35
35
|
}
|
36
36
|
if self._api_version is not None:
|
@@ -93,6 +93,7 @@ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__))
|
|
93
93
|
"workflow_version_exec_config": None,
|
94
94
|
},
|
95
95
|
"parent": None,
|
96
|
+
"links": None,
|
96
97
|
},
|
97
98
|
),
|
98
99
|
(
|
@@ -156,6 +157,7 @@ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__))
|
|
156
157
|
"type": "WORKFLOW_NODE",
|
157
158
|
"span_id": "123e4567-e89b-12d3-a456-426614174000",
|
158
159
|
},
|
160
|
+
"links": None,
|
159
161
|
},
|
160
162
|
),
|
161
163
|
(
|
@@ -191,6 +193,7 @@ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__))
|
|
191
193
|
},
|
192
194
|
},
|
193
195
|
"parent": None,
|
196
|
+
"links": None,
|
194
197
|
},
|
195
198
|
),
|
196
199
|
(
|
@@ -224,6 +227,7 @@ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__))
|
|
224
227
|
},
|
225
228
|
},
|
226
229
|
"parent": None,
|
230
|
+
"links": None,
|
227
231
|
},
|
228
232
|
),
|
229
233
|
(
|
@@ -259,6 +263,7 @@ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__))
|
|
259
263
|
},
|
260
264
|
},
|
261
265
|
"parent": None,
|
266
|
+
"links": None,
|
262
267
|
},
|
263
268
|
),
|
264
269
|
(
|
@@ -294,6 +299,7 @@ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__))
|
|
294
299
|
},
|
295
300
|
},
|
296
301
|
"parent": None,
|
302
|
+
"links": None,
|
297
303
|
},
|
298
304
|
),
|
299
305
|
(
|
@@ -334,6 +340,7 @@ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__))
|
|
334
340
|
"mocked": None,
|
335
341
|
},
|
336
342
|
"parent": None,
|
343
|
+
"links": None,
|
337
344
|
},
|
338
345
|
),
|
339
346
|
(
|
@@ -372,6 +379,7 @@ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__))
|
|
372
379
|
"mocked": None,
|
373
380
|
},
|
374
381
|
"parent": None,
|
382
|
+
"links": None,
|
375
383
|
},
|
376
384
|
),
|
377
385
|
(
|
@@ -405,6 +413,7 @@ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__))
|
|
405
413
|
"mocked": True,
|
406
414
|
},
|
407
415
|
"parent": None,
|
416
|
+
"links": None,
|
408
417
|
},
|
409
418
|
),
|
410
419
|
],
|
vellum/workflows/events/types.py
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
from datetime import datetime
|
2
2
|
import json
|
3
3
|
from uuid import UUID, uuid4
|
4
|
-
from typing import Annotated, Any, Literal, Optional, Union, get_args
|
4
|
+
from typing import Annotated, Any, List, Literal, Optional, Union, get_args
|
5
5
|
|
6
6
|
from pydantic import Field, GetCoreSchemaHandler, Tag, ValidationInfo
|
7
7
|
from pydantic_core import CoreSchema, core_schema
|
8
8
|
|
9
9
|
from vellum.client.core.pydantic_utilities import UniversalBaseModel
|
10
|
+
from vellum.client.types.span_link import SpanLink
|
10
11
|
from vellum.workflows.state.encoder import DefaultStateEncoder
|
11
12
|
from vellum.workflows.types.definition import VellumCodeResourceDefinition
|
12
13
|
from vellum.workflows.types.utils import datetime_now
|
@@ -164,3 +165,4 @@ class BaseEvent(UniversalBaseModel):
|
|
164
165
|
trace_id: UUID
|
165
166
|
span_id: UUID
|
166
167
|
parent: Optional[ParentContext] = None
|
168
|
+
links: Optional[List[SpanLink]] = None
|
@@ -2,7 +2,9 @@ import asyncio
|
|
2
2
|
import json
|
3
3
|
from unittest import mock
|
4
4
|
|
5
|
-
from vellum.workflows.
|
5
|
+
from vellum.workflows.constants import AuthorizationType
|
6
|
+
from vellum.workflows.integrations.mcp_service import MCPHttpClient, MCPService
|
7
|
+
from vellum.workflows.types.definition import MCPServer
|
6
8
|
|
7
9
|
|
8
10
|
def test_mcp_http_client_sse_response():
|
@@ -79,3 +81,40 @@ def test_mcp_http_client_json_response():
|
|
79
81
|
|
80
82
|
# THEN the JSON response should be returned as expected
|
81
83
|
assert result == sample_json_response
|
84
|
+
|
85
|
+
|
86
|
+
def test_mcp_service_bearer_token_auth():
|
87
|
+
"""Test that bearer token auth headers are set correctly"""
|
88
|
+
# GIVEN an MCP server with bearer token auth
|
89
|
+
server = MCPServer(
|
90
|
+
name="test-server",
|
91
|
+
url="https://test.server.com",
|
92
|
+
authorization_type=AuthorizationType.BEARER_TOKEN,
|
93
|
+
bearer_token_value="test-token-123",
|
94
|
+
)
|
95
|
+
|
96
|
+
# WHEN we get auth headers
|
97
|
+
service = MCPService()
|
98
|
+
headers = service._get_auth_headers(server)
|
99
|
+
|
100
|
+
# THEN the Authorization header should be set correctly
|
101
|
+
assert headers == {"Authorization": "Bearer test-token-123"}
|
102
|
+
|
103
|
+
|
104
|
+
def test_mcp_service_api_key_auth():
|
105
|
+
"""Test that API key auth headers are set correctly"""
|
106
|
+
# GIVEN an MCP server with API key auth
|
107
|
+
server = MCPServer(
|
108
|
+
name="test-server",
|
109
|
+
url="https://test.server.com",
|
110
|
+
authorization_type=AuthorizationType.API_KEY,
|
111
|
+
api_key_header_key="X-API-Key",
|
112
|
+
api_key_header_value="api-key-123",
|
113
|
+
)
|
114
|
+
|
115
|
+
# WHEN we get auth headers
|
116
|
+
service = MCPService()
|
117
|
+
headers = service._get_auth_headers(server)
|
118
|
+
|
119
|
+
# THEN the custom API key header should be set correctly
|
120
|
+
assert headers == {"X-API-Key": "api-key-123"}
|
@@ -7,7 +7,7 @@ from vellum.workflows.errors import WorkflowErrorCode
|
|
7
7
|
from vellum.workflows.exceptions import NodeException
|
8
8
|
from vellum.workflows.nodes.bases import BaseNode
|
9
9
|
from vellum.workflows.nodes.bases.base import BaseNodeMeta
|
10
|
-
from vellum.workflows.nodes.utils import parse_type_from_str
|
10
|
+
from vellum.workflows.nodes.utils import parse_type_from_str, wrap_inputs_for_backward_compatibility
|
11
11
|
from vellum.workflows.types.core import EntityInputsInterface
|
12
12
|
from vellum.workflows.types.generics import StateType
|
13
13
|
from vellum.workflows.types.utils import get_original_base
|
@@ -86,9 +86,10 @@ class TemplatingNode(BaseNode[StateType], Generic[StateType, _OutputType], metac
|
|
86
86
|
|
87
87
|
def _render_template(self) -> str:
|
88
88
|
try:
|
89
|
+
wrapped_inputs = wrap_inputs_for_backward_compatibility(self.inputs)
|
89
90
|
return render_sandboxed_jinja_template(
|
90
91
|
template=self.template,
|
91
|
-
input_values=
|
92
|
+
input_values=wrapped_inputs,
|
92
93
|
jinja_custom_filters={**self.jinja_custom_filters},
|
93
94
|
jinja_globals=self.jinja_globals,
|
94
95
|
)
|
@@ -317,3 +317,132 @@ def test_api_error_templating_node():
|
|
317
317
|
|
318
318
|
# THEN the output should be empty string
|
319
319
|
assert outputs.result == ""
|
320
|
+
|
321
|
+
|
322
|
+
@pytest.mark.parametrize(
|
323
|
+
"template,inputs,expected_result",
|
324
|
+
[
|
325
|
+
# String value access
|
326
|
+
("{{ text_input.value }}", {"text_input": "hello world"}, "hello world"),
|
327
|
+
# Function call value access
|
328
|
+
(
|
329
|
+
"{{ func.value.name }}",
|
330
|
+
{"func": FunctionCall(name="test_function", arguments={"key": "value"})},
|
331
|
+
"test_function",
|
332
|
+
),
|
333
|
+
# Array item value access
|
334
|
+
("{{ items[0].value }}", {"items": ["apple"]}, "apple"),
|
335
|
+
],
|
336
|
+
ids=["string_value", "function_call_value", "array_item_value"],
|
337
|
+
)
|
338
|
+
def test_templating_node__value_access_patterns_str(template, inputs, expected_result):
|
339
|
+
# GIVEN a templating node that accesses wrapper value properties
|
340
|
+
class TemplateNode(TemplatingNode[BaseState, str]):
|
341
|
+
pass
|
342
|
+
|
343
|
+
# Set template and inputs dynamically
|
344
|
+
TemplateNode.template = template
|
345
|
+
TemplateNode.inputs = inputs
|
346
|
+
|
347
|
+
# WHEN the node is run
|
348
|
+
node = TemplateNode()
|
349
|
+
outputs = node.run()
|
350
|
+
|
351
|
+
# THEN the value is accessible
|
352
|
+
assert outputs.result == expected_result
|
353
|
+
|
354
|
+
|
355
|
+
@pytest.mark.parametrize(
|
356
|
+
"template,inputs,expected_result",
|
357
|
+
[
|
358
|
+
# Dict value access
|
359
|
+
("{{ data.value }}", {"data": {"name": "test", "score": 42}}, {"name": "test", "score": 42}),
|
360
|
+
# List value access
|
361
|
+
("{{ items.value }}", {"items": ["item1", "item2", "item3"]}, ["item1", "item2", "item3"]),
|
362
|
+
],
|
363
|
+
ids=["dict_value", "list_value"],
|
364
|
+
)
|
365
|
+
def test_templating_node__value_access_patterns_json(template, inputs, expected_result):
|
366
|
+
# GIVEN a templating node that accesses wrapper value properties
|
367
|
+
class TemplateNode(TemplatingNode[BaseState, Json]):
|
368
|
+
pass
|
369
|
+
|
370
|
+
# Set template and inputs dynamically
|
371
|
+
TemplateNode.template = template
|
372
|
+
TemplateNode.inputs = inputs
|
373
|
+
|
374
|
+
# WHEN the node is run
|
375
|
+
node = TemplateNode()
|
376
|
+
outputs = node.run()
|
377
|
+
|
378
|
+
# THEN the value is accessible
|
379
|
+
assert outputs.result == expected_result
|
380
|
+
|
381
|
+
|
382
|
+
@pytest.mark.parametrize(
|
383
|
+
"template,inputs,expected_result",
|
384
|
+
[
|
385
|
+
# String type access
|
386
|
+
("{{ text_input.type }}", {"text_input": "hello world"}, "STRING"),
|
387
|
+
# Function call type access
|
388
|
+
("{{ func.type }}", {"func": FunctionCall(name="test_function", arguments={"key": "value"})}, "FUNCTION_CALL"),
|
389
|
+
],
|
390
|
+
ids=["string_type", "function_call_type"],
|
391
|
+
)
|
392
|
+
def test_templating_node__type_access_patterns(template, inputs, expected_result):
|
393
|
+
# GIVEN a templating node that accesses wrapper type properties
|
394
|
+
class TemplateNode(TemplatingNode[BaseState, str]):
|
395
|
+
pass
|
396
|
+
|
397
|
+
# Set template and inputs dynamically
|
398
|
+
TemplateNode.template = template
|
399
|
+
TemplateNode.inputs = inputs
|
400
|
+
|
401
|
+
# WHEN the node is run
|
402
|
+
node = TemplateNode()
|
403
|
+
outputs = node.run()
|
404
|
+
|
405
|
+
# THEN the type is accessible
|
406
|
+
assert outputs.result == expected_result
|
407
|
+
|
408
|
+
|
409
|
+
def test_templating_node__nested_dict_access():
|
410
|
+
# GIVEN a templating node with nested dict access
|
411
|
+
class TemplateNode(TemplatingNode[BaseState, str]):
|
412
|
+
template = "{{ data.user.name }}"
|
413
|
+
inputs = {"data": {"user": {"name": "John Doe", "age": 30}, "status": "active"}}
|
414
|
+
|
415
|
+
# WHEN the node is run
|
416
|
+
node = TemplateNode()
|
417
|
+
outputs = node.run()
|
418
|
+
|
419
|
+
# THEN nested properties are accessible
|
420
|
+
assert outputs.result == "John Doe"
|
421
|
+
|
422
|
+
|
423
|
+
def test_templating_node__list_iteration_wrapper_access():
|
424
|
+
# GIVEN a templating node that iterates over list with wrapper access
|
425
|
+
class TemplateNode(TemplatingNode[BaseState, str]):
|
426
|
+
template = "{% for item in items %}{{ item.value }}{% if not loop.last %},{% endif %}{% endfor %}"
|
427
|
+
inputs = {"items": ["apple", "banana", "cherry"]}
|
428
|
+
|
429
|
+
# WHEN the node is run
|
430
|
+
node = TemplateNode()
|
431
|
+
outputs = node.run()
|
432
|
+
|
433
|
+
# THEN list iteration with wrapper access works
|
434
|
+
assert outputs.result == "apple,banana,cherry"
|
435
|
+
|
436
|
+
|
437
|
+
def test_templating_node__conditional_type_checking():
|
438
|
+
# GIVEN a templating node with conditional type checking
|
439
|
+
class TemplateNode(TemplatingNode[BaseState, str]):
|
440
|
+
template = "{% if input.type == 'STRING' %}{{ input.value }}{% else %}unknown{% endif %}"
|
441
|
+
inputs = {"input": "test string"}
|
442
|
+
|
443
|
+
# WHEN the node is run
|
444
|
+
node = TemplateNode()
|
445
|
+
outputs = node.run()
|
446
|
+
|
447
|
+
# THEN conditional type checking works
|
448
|
+
assert outputs.result == "test string"
|
@@ -28,6 +28,7 @@ from vellum.workflows.errors.types import vellum_error_to_workflow_error
|
|
28
28
|
from vellum.workflows.events.types import default_serializer
|
29
29
|
from vellum.workflows.exceptions import NodeException
|
30
30
|
from vellum.workflows.nodes.displayable.bases.base_prompt_node import BasePromptNode
|
31
|
+
from vellum.workflows.nodes.displayable.bases.utils import process_additional_prompt_outputs
|
31
32
|
from vellum.workflows.outputs import BaseOutput
|
32
33
|
from vellum.workflows.types import MergeBehavior
|
33
34
|
from vellum.workflows.types.definition import DeploymentDefinition
|
@@ -197,6 +198,17 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
|
|
197
198
|
elif event.state == "STREAMING":
|
198
199
|
yield BaseOutput(name="results", delta=event.output.value)
|
199
200
|
elif event.state == "FULFILLED":
|
201
|
+
if event.meta and event.meta.finish_reason == "LENGTH":
|
202
|
+
text_value, json_value = process_additional_prompt_outputs(event.outputs)
|
203
|
+
if text_value == "":
|
204
|
+
raise NodeException(
|
205
|
+
message=(
|
206
|
+
"Maximum tokens reached before model could output any content. "
|
207
|
+
"Consider increasing the max_tokens Prompt Parameter."
|
208
|
+
),
|
209
|
+
code=WorkflowErrorCode.INVALID_OUTPUTS,
|
210
|
+
)
|
211
|
+
|
200
212
|
outputs = event.outputs
|
201
213
|
yield BaseOutput(name="results", value=event.outputs)
|
202
214
|
elif event.state == "REJECTED":
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py
CHANGED
@@ -20,6 +20,7 @@ from vellum import (
|
|
20
20
|
)
|
21
21
|
from vellum.client.types.execute_prompt_event import ExecutePromptEvent
|
22
22
|
from vellum.client.types.fulfilled_execute_prompt_event import FulfilledExecutePromptEvent
|
23
|
+
from vellum.client.types.fulfilled_prompt_execution_meta import FulfilledPromptExecutionMeta
|
23
24
|
from vellum.client.types.initiated_execute_prompt_event import InitiatedExecutePromptEvent
|
24
25
|
from vellum.client.types.prompt_output import PromptOutput
|
25
26
|
from vellum.client.types.prompt_request_string_input import PromptRequestStringInput
|
@@ -684,3 +685,43 @@ def test_inline_prompt_node__invalid_function_type():
|
|
684
685
|
# AND the error should have the correct code and message
|
685
686
|
assert excinfo.value.code == WorkflowErrorCode.INVALID_INPUTS
|
686
687
|
assert "`not_a_function` is not a valid function definition" == str(excinfo.value)
|
688
|
+
|
689
|
+
|
690
|
+
def test_inline_prompt_node__empty_string_output_with_length_finish_reason(vellum_adhoc_prompt_client):
|
691
|
+
"""
|
692
|
+
Tests that InlinePromptNode raises NodeException for empty string output with LENGTH finish_reason.
|
693
|
+
"""
|
694
|
+
|
695
|
+
# GIVEN an InlinePromptNode with basic configuration
|
696
|
+
class TestNode(InlinePromptNode):
|
697
|
+
ml_model = "test-model"
|
698
|
+
blocks = []
|
699
|
+
prompt_inputs = {}
|
700
|
+
|
701
|
+
expected_outputs: List[PromptOutput] = [
|
702
|
+
StringVellumValue(value=""),
|
703
|
+
]
|
704
|
+
|
705
|
+
def generate_prompt_events(*args: Any, **kwargs: Any) -> Iterator[ExecutePromptEvent]:
|
706
|
+
execution_id = str(uuid4())
|
707
|
+
events: List[ExecutePromptEvent] = [
|
708
|
+
InitiatedExecutePromptEvent(execution_id=execution_id),
|
709
|
+
FulfilledExecutePromptEvent(
|
710
|
+
execution_id=execution_id,
|
711
|
+
outputs=expected_outputs,
|
712
|
+
meta=FulfilledPromptExecutionMeta(finish_reason="LENGTH"),
|
713
|
+
),
|
714
|
+
]
|
715
|
+
yield from events
|
716
|
+
|
717
|
+
vellum_adhoc_prompt_client.adhoc_execute_prompt_stream.side_effect = generate_prompt_events
|
718
|
+
|
719
|
+
# WHEN the node is run
|
720
|
+
node = TestNode()
|
721
|
+
|
722
|
+
# THEN it should raise a NodeException with INVALID_OUTPUTS error code
|
723
|
+
with pytest.raises(NodeException) as excinfo:
|
724
|
+
list(node.run())
|
725
|
+
|
726
|
+
# AND the exception should have the correct error code
|
727
|
+
assert excinfo.value.code == WorkflowErrorCode.INVALID_OUTPUTS
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import enum
|
2
2
|
import json
|
3
|
-
from typing import Any, List, Union, cast
|
3
|
+
from typing import Any, List, Optional, Tuple, Union, cast
|
4
4
|
|
5
|
+
from vellum import PromptOutput
|
5
6
|
from vellum.client.types.array_vellum_value import ArrayVellumValue
|
6
7
|
from vellum.client.types.array_vellum_value_request import ArrayVellumValueRequest
|
7
8
|
from vellum.client.types.audio_vellum_value import AudioVellumValue
|
@@ -123,3 +124,39 @@ def primitive_to_vellum_value_request(value: Any) -> VellumValueRequest:
|
|
123
124
|
raise ValueError(f"Unsupported variable type: {vellum_value.__class__.__name__}")
|
124
125
|
|
125
126
|
return vellum_value_request_class.model_validate(vellum_value.model_dump())
|
127
|
+
|
128
|
+
|
129
|
+
def process_additional_prompt_outputs(outputs: List[PromptOutput]) -> Tuple[str, Optional[Any]]:
|
130
|
+
"""
|
131
|
+
Process prompt outputs using the same logic as prompt nodes to determine text output.
|
132
|
+
|
133
|
+
Args:
|
134
|
+
outputs: List of prompt outputs to process
|
135
|
+
|
136
|
+
Returns:
|
137
|
+
The text representation of the outputs joined with newlines
|
138
|
+
The JSON representation of the outputs
|
139
|
+
"""
|
140
|
+
string_outputs = []
|
141
|
+
json_output = None
|
142
|
+
for output in outputs:
|
143
|
+
if output.value is None:
|
144
|
+
continue
|
145
|
+
|
146
|
+
if output.type == "STRING":
|
147
|
+
string_outputs.append(output.value)
|
148
|
+
try:
|
149
|
+
json_output = json.loads(output.value)
|
150
|
+
except (json.JSONDecodeError, TypeError):
|
151
|
+
pass
|
152
|
+
elif output.type == "JSON":
|
153
|
+
string_outputs.append(json.dumps(output.value, indent=4))
|
154
|
+
json_output = output.value
|
155
|
+
elif output.type == "FUNCTION_CALL":
|
156
|
+
string_outputs.append(output.value.model_dump_json(indent=4))
|
157
|
+
elif output.type == "THINKING":
|
158
|
+
continue
|
159
|
+
else:
|
160
|
+
string_outputs.append(output.value.message)
|
161
|
+
|
162
|
+
return "\n".join(string_outputs), json_output
|
@@ -4,13 +4,10 @@ import sys
|
|
4
4
|
import traceback
|
5
5
|
from typing import Any, Optional, Tuple, Union
|
6
6
|
|
7
|
-
from pydantic import BaseModel
|
8
|
-
|
9
7
|
from vellum.workflows.errors.types import WorkflowErrorCode
|
10
8
|
from vellum.workflows.exceptions import NodeException
|
11
|
-
from vellum.workflows.nodes.utils import cast_to_output_type
|
9
|
+
from vellum.workflows.nodes.utils import cast_to_output_type, wrap_inputs_for_backward_compatibility
|
12
10
|
from vellum.workflows.state.context import WorkflowContext
|
13
|
-
from vellum.workflows.types.code_execution_node_wrappers import ListWrapper, clean_for_dict_wrapper
|
14
11
|
from vellum.workflows.types.core import EntityInputsInterface
|
15
12
|
|
16
13
|
|
@@ -51,23 +48,9 @@ def run_code_inline(
|
|
51
48
|
print_line = f"{' '.join(str_args)}\n"
|
52
49
|
log_buffer.write(print_line)
|
53
50
|
|
54
|
-
|
55
|
-
if isinstance(value, list):
|
56
|
-
return ListWrapper(
|
57
|
-
[
|
58
|
-
# Convert VellumValue to dict with its fields
|
59
|
-
(
|
60
|
-
item.model_dump()
|
61
|
-
if isinstance(item, BaseModel)
|
62
|
-
else clean_for_dict_wrapper(item) if isinstance(item, (dict, list, str)) else item
|
63
|
-
)
|
64
|
-
for item in value
|
65
|
-
]
|
66
|
-
)
|
67
|
-
return clean_for_dict_wrapper(value)
|
68
|
-
|
51
|
+
wrapped_inputs = wrap_inputs_for_backward_compatibility(inputs)
|
69
52
|
exec_globals = {
|
70
|
-
"__arg__inputs":
|
53
|
+
"__arg__inputs": wrapped_inputs,
|
71
54
|
"__arg__out": None,
|
72
55
|
"print": _inline_print,
|
73
56
|
}
|
@@ -1,10 +1,10 @@
|
|
1
|
-
import json
|
2
1
|
from typing import Any, Dict, Generic, Iterator, Type, Union
|
3
2
|
|
4
3
|
from vellum.workflows.constants import undefined
|
5
4
|
from vellum.workflows.errors import WorkflowErrorCode
|
6
5
|
from vellum.workflows.exceptions import NodeException
|
7
6
|
from vellum.workflows.nodes.displayable.bases import BaseInlinePromptNode as BaseInlinePromptNode
|
7
|
+
from vellum.workflows.nodes.displayable.bases.utils import process_additional_prompt_outputs
|
8
8
|
from vellum.workflows.outputs import BaseOutput
|
9
9
|
from vellum.workflows.types import MergeBehavior
|
10
10
|
from vellum.workflows.types.generics import StateType
|
@@ -45,31 +45,8 @@ class InlinePromptNode(BaseInlinePromptNode[StateType], Generic[StateType]):
|
|
45
45
|
code=WorkflowErrorCode.INTERNAL_ERROR,
|
46
46
|
)
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
for output in outputs:
|
52
|
-
if output.value is None:
|
53
|
-
continue
|
54
|
-
|
55
|
-
if output.type == "STRING":
|
56
|
-
string_outputs.append(output.value)
|
57
|
-
try:
|
58
|
-
json_output = json.loads(output.value)
|
59
|
-
except (json.JSONDecodeError, TypeError):
|
60
|
-
pass
|
61
|
-
elif output.type == "JSON":
|
62
|
-
string_outputs.append(json.dumps(output.value, indent=4))
|
63
|
-
json_output = output.value
|
64
|
-
elif output.type == "FUNCTION_CALL":
|
65
|
-
string_outputs.append(output.value.model_dump_json(indent=4))
|
66
|
-
elif output.type == "THINKING":
|
67
|
-
continue
|
68
|
-
else:
|
69
|
-
string_outputs.append(output.value.message)
|
70
|
-
|
71
|
-
value = "\n".join(string_outputs)
|
72
|
-
yield BaseOutput(name="text", value=value)
|
48
|
+
text_output, json_output = process_additional_prompt_outputs(outputs)
|
49
|
+
yield BaseOutput(name="text", value=text_output)
|
73
50
|
|
74
51
|
if json_output:
|
75
52
|
yield BaseOutput(name="json", value=json_output)
|
@@ -1,10 +1,10 @@
|
|
1
|
-
import json
|
2
1
|
from typing import Any, Dict, Iterator, Type, Union
|
3
2
|
|
4
3
|
from vellum.workflows.constants import undefined
|
5
4
|
from vellum.workflows.errors import WorkflowErrorCode
|
6
5
|
from vellum.workflows.exceptions import NodeException
|
7
6
|
from vellum.workflows.nodes.displayable.bases import BasePromptDeploymentNode as BasePromptDeploymentNode
|
7
|
+
from vellum.workflows.nodes.displayable.bases.utils import process_additional_prompt_outputs
|
8
8
|
from vellum.workflows.outputs import BaseOutput
|
9
9
|
from vellum.workflows.types import MergeBehavior
|
10
10
|
from vellum.workflows.types.generics import StateType
|
@@ -48,30 +48,8 @@ class PromptDeploymentNode(BasePromptDeploymentNode[StateType]):
|
|
48
48
|
code=WorkflowErrorCode.INTERNAL_ERROR,
|
49
49
|
)
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
for output in outputs:
|
55
|
-
if output.value is None:
|
56
|
-
continue
|
57
|
-
|
58
|
-
if output.type == "STRING":
|
59
|
-
string_outputs.append(output.value)
|
60
|
-
try:
|
61
|
-
json_output = json.loads(output.value)
|
62
|
-
except (json.JSONDecodeError, TypeError):
|
63
|
-
pass
|
64
|
-
elif output.type == "JSON":
|
65
|
-
string_outputs.append(json.dumps(output.value, indent=4))
|
66
|
-
elif output.type == "FUNCTION_CALL":
|
67
|
-
string_outputs.append(output.value.model_dump_json(indent=4))
|
68
|
-
elif output.type == "THINKING":
|
69
|
-
continue
|
70
|
-
else:
|
71
|
-
string_outputs.append(output.value.message)
|
72
|
-
|
73
|
-
value = "\n".join(string_outputs)
|
74
|
-
yield BaseOutput(name="text", value=value)
|
51
|
+
text_output, json_output = process_additional_prompt_outputs(outputs)
|
52
|
+
yield BaseOutput(name="text", value=text_output)
|
75
53
|
|
76
54
|
if json_output:
|
77
55
|
yield BaseOutput(name="json", value=json_output)
|
vellum/workflows/nodes/utils.py
CHANGED
@@ -15,7 +15,12 @@ from vellum.workflows.nodes import BaseNode
|
|
15
15
|
from vellum.workflows.nodes.bases.base_adornment_node import BaseAdornmentNode
|
16
16
|
from vellum.workflows.ports.port import Port
|
17
17
|
from vellum.workflows.state.base import BaseState
|
18
|
-
from vellum.workflows.types.code_execution_node_wrappers import
|
18
|
+
from vellum.workflows.types.code_execution_node_wrappers import (
|
19
|
+
DictWrapper,
|
20
|
+
ListWrapper,
|
21
|
+
StringValueWrapper,
|
22
|
+
clean_for_dict_wrapper,
|
23
|
+
)
|
19
24
|
from vellum.workflows.types.core import Json
|
20
25
|
from vellum.workflows.types.generics import NodeType
|
21
26
|
|
@@ -261,3 +266,23 @@ def cast_to_output_type(result: Any, output_type: Any) -> Any:
|
|
261
266
|
code=WorkflowErrorCode.INVALID_OUTPUTS,
|
262
267
|
message=f"Expected an output of type '{output_type_name}', but received '{result_type_name}'",
|
263
268
|
)
|
269
|
+
|
270
|
+
|
271
|
+
def wrap_inputs_for_backward_compatibility(inputs: Dict[str, Any]) -> Dict[str, Any]:
|
272
|
+
"""Wrap inputs with backward-compatible wrapper classes for legacy .value and .type support."""
|
273
|
+
|
274
|
+
def _wrap_single_value(value: Any) -> Any:
|
275
|
+
if isinstance(value, list):
|
276
|
+
return ListWrapper(
|
277
|
+
[
|
278
|
+
(
|
279
|
+
item.model_dump()
|
280
|
+
if isinstance(item, BaseModel)
|
281
|
+
else clean_for_dict_wrapper(item) if isinstance(item, (dict, list, str)) else item
|
282
|
+
)
|
283
|
+
for item in value
|
284
|
+
]
|
285
|
+
)
|
286
|
+
return clean_for_dict_wrapper(value)
|
287
|
+
|
288
|
+
return {name: _wrap_single_value(value) for name, value in inputs.items()}
|
@@ -121,6 +121,7 @@ class ComposioToolDefinition(UniversalBaseModel):
|
|
121
121
|
class MCPServer(UniversalBaseModel):
|
122
122
|
type: Literal["MCP_SERVER"] = "MCP_SERVER"
|
123
123
|
name: str
|
124
|
+
description: str = "" # We don't use this field, its for compatibility with UI
|
124
125
|
url: str
|
125
126
|
authorization_type: Optional[AuthorizationType] = None
|
126
127
|
bearer_token_value: Optional[Union[str, EnvironmentVariableReference]] = None
|
@@ -89,6 +89,10 @@ def compile_annotation(annotation: Optional[Any], defs: dict[str, Any]) -> dict:
|
|
89
89
|
# Mypy is incorrect here, the `annotation` attribute is defined on `FieldInfo`
|
90
90
|
field_annotation = field.annotation # type: ignore[attr-defined]
|
91
91
|
properties[field_name] = compile_annotation(field_annotation, defs)
|
92
|
+
|
93
|
+
if hasattr(field, "description") and field.description is not None:
|
94
|
+
properties[field_name]["description"] = field.description # type: ignore[attr-defined]
|
95
|
+
|
92
96
|
if field.default is PydanticUndefined:
|
93
97
|
required.append(field_name)
|
94
98
|
else:
|
@@ -4,7 +4,7 @@ from enum import Enum
|
|
4
4
|
from unittest.mock import Mock
|
5
5
|
from typing import Annotated, Dict, List, Literal, Optional, Tuple, Union
|
6
6
|
|
7
|
-
from pydantic import BaseModel
|
7
|
+
from pydantic import BaseModel, Field
|
8
8
|
|
9
9
|
from vellum.client.types.function_definition import FunctionDefinition
|
10
10
|
from vellum.client.types.string_vellum_value import StringVellumValue
|
@@ -206,7 +206,7 @@ def test_compile_function_definition__dataclasses():
|
|
206
206
|
def test_compile_function_definition__pydantic():
|
207
207
|
# GIVEN a function with a pydantic model
|
208
208
|
class MyPydanticModel(BaseModel):
|
209
|
-
a: int
|
209
|
+
a: int = Field(description="The first number")
|
210
210
|
b: str
|
211
211
|
|
212
212
|
def my_function(c: MyPydanticModel):
|
@@ -225,7 +225,10 @@ def test_compile_function_definition__pydantic():
|
|
225
225
|
"$defs": {
|
226
226
|
"MyPydanticModel": {
|
227
227
|
"type": "object",
|
228
|
-
"properties": {
|
228
|
+
"properties": {
|
229
|
+
"a": {"type": "integer", "description": "The first number"},
|
230
|
+
"b": {"type": "string"},
|
231
|
+
},
|
229
232
|
"required": ["a", "b"],
|
230
233
|
}
|
231
234
|
},
|
@@ -1,14 +1,14 @@
|
|
1
1
|
vellum_cli/CONTRIBUTING.md,sha256=FtDC7BGxSeMnwCXAUssFsAIElXtmJE-O5Z7BpolcgvI,2935
|
2
2
|
vellum_cli/README.md,sha256=2NudRoLzWxNKqnuVy1JuQ7DerIaxWGYkrH8kMd-asIE,90
|
3
|
-
vellum_cli/__init__.py,sha256=
|
3
|
+
vellum_cli/__init__.py,sha256=rHcUFsfu-nivhX02R-6dmYr9ee6LMA-wy2DrFnOhC4Q,13030
|
4
4
|
vellum_cli/aliased_group.py,sha256=ugW498j0yv4ALJ8vS9MsO7ctDW7Jlir9j6nE_uHAP8c,3363
|
5
|
-
vellum_cli/config.py,sha256=
|
5
|
+
vellum_cli/config.py,sha256=qJrd8W__UZZaUMAG6BO3sxfkgpCoOS4NA3QfqneW-jE,9588
|
6
6
|
vellum_cli/image_push.py,sha256=eeOBqKtKkPu6Kgm_jQCVCivogzAcdlIlkv61-QxH67c,11006
|
7
7
|
vellum_cli/init.py,sha256=WpnMXPItPmh0f0bBGIer3p-e5gu8DUGwSArT_FuoMEw,5093
|
8
8
|
vellum_cli/logger.py,sha256=dcM_OmgqXLo93vDYswO5ylyUQQcTfnA5GTd5tbIt3wM,1446
|
9
9
|
vellum_cli/ping.py,sha256=p_BCCRjgPhng6JktuECtkDQLbhopt6JpmrtGoLnLJT8,1161
|
10
10
|
vellum_cli/pull.py,sha256=udYyPlJ6VKDdh78rApNJOZgxHl82fcV6iGnRPSdX1LY,14750
|
11
|
-
vellum_cli/push.py,sha256=
|
11
|
+
vellum_cli/push.py,sha256=KpBGq7B-ffwa9QTHsTRSk73l-tfKc3gyiBSn9Pwlsak,11878
|
12
12
|
vellum_cli/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
13
|
vellum_cli/tests/conftest.py,sha256=wx3PlJjVB0HRf5dr2b_idOIw27WPPl0J0FNbhIJJaVk,1689
|
14
14
|
vellum_cli/tests/test_config.py,sha256=uvKGDc8BoVyT9_H0Z-g8469zVxomn6Oi3Zj-vK7O_wU,2631
|
@@ -17,8 +17,8 @@ vellum_cli/tests/test_image_push_error_handling.py,sha256=QRH0eYNEEIkD2-EVFQWYex
|
|
17
17
|
vellum_cli/tests/test_init.py,sha256=8UOc_ThfouR4ja5cCl_URuLk7ohr9JXfCnG4yka1OUQ,18754
|
18
18
|
vellum_cli/tests/test_main.py,sha256=qDZG-aQauPwBwM6A2DIu1494n47v3pL28XakTbLGZ-k,272
|
19
19
|
vellum_cli/tests/test_ping.py,sha256=b3aQLd-N59_8w2rRiWqwpB1rlHaKEYVbAj1Y3hi7A-g,2605
|
20
|
-
vellum_cli/tests/test_pull.py,sha256=
|
21
|
-
vellum_cli/tests/test_push.py,sha256=
|
20
|
+
vellum_cli/tests/test_pull.py,sha256=WcRtp5N27CbfBv7vx2wNhLTsSacYw7TiBVVXcI7ZMW4,50014
|
21
|
+
vellum_cli/tests/test_push.py,sha256=10G-H88tdiYvg9CaC8OXOf25UEzWkWWB01vNhuxzjog,41944
|
22
22
|
vellum_ee/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
23
|
vellum_ee/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
24
|
vellum_ee/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -64,7 +64,7 @@ vellum_ee/workflows/display/nodes/vellum/tests/test_retry_node.py,sha256=WyqX_g-
|
|
64
64
|
vellum_ee/workflows/display/nodes/vellum/tests/test_search_node.py,sha256=KvByxgbUkVyfPIVxTUBUk6a92JiJMi8eReZWxzfPExU,3864
|
65
65
|
vellum_ee/workflows/display/nodes/vellum/tests/test_subworkflow_deployment_node.py,sha256=BUzHJgjdWnPeZxjFjHfDBKnbFjYjnbXPjc-1hne1B2Y,3965
|
66
66
|
vellum_ee/workflows/display/nodes/vellum/tests/test_templating_node.py,sha256=LSk2gx9TpGXbAqKe8dggQW8yJZqj-Cf0EGJFeGGlEcw,3321
|
67
|
-
vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py,sha256=
|
67
|
+
vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py,sha256=0D1q5yyt5fr1sC2UgBC-1OWXvGcwRx40xvpM7qXyDIA,24819
|
68
68
|
vellum_ee/workflows/display/nodes/vellum/tests/test_try_node.py,sha256=Khjsb53PKpZuyhKoRMgKAL45eGp5hZqXvHmVeQWRw4w,2289
|
69
69
|
vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py,sha256=rHybfUAWwa0LlstQTNthGb-zYXrUCLADFtn_4SGsbw8,4807
|
70
70
|
vellum_ee/workflows/display/nodes/vellum/try_node.py,sha256=47fOnSCEFnY8th9m2yTYlgnoUuzgyRZdjg-SXwn--lk,4079
|
@@ -97,7 +97,7 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_n
|
|
97
97
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py,sha256=A7Ef8P1-Nyvsb97bumKT9W2R1LuZaY9IKFV-7iRueog,4010
|
98
98
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_composio_serialization.py,sha256=oVXCjkU0G56QJmqnd_xIwF3D9bhJwALFibM2wmRhwUk,3739
|
99
99
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py,sha256=Sg82qV5NCzQDy-RD90hA6QaHgFHOq6ESNkbWXygsnNw,26367
|
100
|
-
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_mcp_serialization.py,sha256=
|
100
|
+
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_mcp_serialization.py,sha256=QhQbijeCnFeX1i3SMjHJg2WVAEt5JEO3dhFRv-mofdA,2458
|
101
101
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py,sha256=-7NvpYUZEl2T15AS9MPt_scyhKmUmS3wEPa320sgWOI,10085
|
102
102
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_workflow_deployment_serialization.py,sha256=XIZZr5POo2NLn2uEWm9EC3rejeBMoO4X-JtzTH6mvp4,4074
|
103
103
|
vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py,sha256=pLCyMScV88DTBXRH7jXaXOEA1GBq8NIipCUFwIAWnwI,2771
|
@@ -150,7 +150,7 @@ vellum/client/README.md,sha256=gxc7JlJRBrBZpN5LHa2ORxYTRHFLPnWmnIugN8pmQh4,5600
|
|
150
150
|
vellum/client/__init__.py,sha256=LOu_TklkJG01SgXIpPWDhOX2QvKDyd2ZbQyr5H0m31I,72349
|
151
151
|
vellum/client/core/__init__.py,sha256=lTcqUPXcx4112yLDd70RAPeqq6tu3eFMe1pKOqkW9JQ,1562
|
152
152
|
vellum/client/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
|
153
|
-
vellum/client/core/client_wrapper.py,sha256=
|
153
|
+
vellum/client/core/client_wrapper.py,sha256=UTXev7Ggseqsagx6lWuso8TzaZN7pWxlZdlinovd_p0,2840
|
154
154
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
155
155
|
vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
|
156
156
|
vellum/client/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
|
@@ -1669,8 +1669,8 @@ vellum/workflows/events/relational_threads.py,sha256=zmLrBCBYpdpQV0snKH3HleST-_h
|
|
1669
1669
|
vellum/workflows/events/stream.py,sha256=xhXJTZirFi0xad5neAQNogrIQ4h47fpnKbVC3vCM5Js,889
|
1670
1670
|
vellum/workflows/events/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1671
1671
|
vellum/workflows/events/tests/test_basic_workflow.py,sha256=Pj6orHsXz37jWC5FARi0Sx2Gjf99Owri2Cvr6Chb79k,1765
|
1672
|
-
vellum/workflows/events/tests/test_event.py,sha256=
|
1673
|
-
vellum/workflows/events/types.py,sha256=
|
1672
|
+
vellum/workflows/events/tests/test_event.py,sha256=c2pM8ZOuES_8XjLYP4cU4cChrZUZ1ZZ3HUNIaaPAxXk,18411
|
1673
|
+
vellum/workflows/events/types.py,sha256=5iU8KmS_fl0l42XBQshiNLPl2yLdPMEQKQ8nYP--0L0,4940
|
1674
1674
|
vellum/workflows/events/workflow.py,sha256=gjg4Dt5i40jaTMK_-AaGtW9lzX1JGn3FUAu1XqhduJ8,8753
|
1675
1675
|
vellum/workflows/exceptions.py,sha256=NiBiR3ggfmPxBVqD-H1SqmjI-7mIn0EStSN1BqApvCM,1213
|
1676
1676
|
vellum/workflows/expressions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1728,7 +1728,7 @@ vellum/workflows/inputs/tests/test_inputs.py,sha256=lioA8917mFLYq7Ml69UNkqUjcWbb
|
|
1728
1728
|
vellum/workflows/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1729
1729
|
vellum/workflows/integrations/composio_service.py,sha256=rSliaZtNiBcDSvDxz9k5i1KkyUIrbxyegu0yU9cDByU,6023
|
1730
1730
|
vellum/workflows/integrations/mcp_service.py,sha256=9DYb8dg2_kgc1UOu830kxhaFlt9yTbhKPhK3L6kb1t4,9831
|
1731
|
-
vellum/workflows/integrations/tests/test_mcp_service.py,sha256=
|
1731
|
+
vellum/workflows/integrations/tests/test_mcp_service.py,sha256=xQVtcqRbgq6Bx4pyxLdgUtZFNGISPfISvpXcyd0U6Hc,4595
|
1732
1732
|
vellum/workflows/logging.py,sha256=_a217XogktV4Ncz6xKFz7WfYmZAzkfVRVuC0rWob8ls,437
|
1733
1733
|
vellum/workflows/nodes/__init__.py,sha256=aVdQVv7Y3Ro3JlqXGpxwaU2zrI06plDHD2aumH5WUIs,1157
|
1734
1734
|
vellum/workflows/nodes/bases/__init__.py,sha256=cniHuz_RXdJ4TQgD8CBzoiKDiPxg62ErdVpCbWICX64,58
|
@@ -1753,8 +1753,8 @@ vellum/workflows/nodes/core/retry_node/node.py,sha256=EM4ya8Myr7ADllpjt9q-BAhB3h
|
|
1753
1753
|
vellum/workflows/nodes/core/retry_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1754
1754
|
vellum/workflows/nodes/core/retry_node/tests/test_node.py,sha256=PCvD_XROP26k4cVYOdSQUfkDdbTljAJxtOTFzOUoS8c,4450
|
1755
1755
|
vellum/workflows/nodes/core/templating_node/__init__.py,sha256=GmyuYo81_A1_Bz6id69ozVFS6FKiuDsZTiA3I6MaL2U,70
|
1756
|
-
vellum/workflows/nodes/core/templating_node/node.py,sha256=
|
1757
|
-
vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py,sha256=
|
1756
|
+
vellum/workflows/nodes/core/templating_node/node.py,sha256=mn0JEbORWaM-mR7fgUZy-BItZCup8CaxZQaY_g3TSEE,3855
|
1757
|
+
vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py,sha256=RzX00apXes3Kz7AY0a_Ewx65byRwp2FFc1ceh0AWUOc,14381
|
1758
1758
|
vellum/workflows/nodes/core/try_node/__init__.py,sha256=JVD4DrldTIqFQQFrubs9KtWCCc0YCAc7Fzol5ZWIWeM,56
|
1759
1759
|
vellum/workflows/nodes/core/try_node/node.py,sha256=XdyOvlwQ3m4h0-_WNtaBl2t_CdlzPXclulkLOtUcX3E,4388
|
1760
1760
|
vellum/workflows/nodes/core/try_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1772,22 +1772,22 @@ vellum/workflows/nodes/displayable/bases/api_node/tests/test_node.py,sha256=5C59
|
|
1772
1772
|
vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py,sha256=Org3xTvgp1pA0uUXFfnJr29D3HzCey2lEdYF4zbIUgo,70
|
1773
1773
|
vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=ea20icDM1HB942wkH-XtXNSNCBDcjeOiN3vowkHL4fs,4477
|
1774
1774
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py,sha256=Hl35IAoepRpE-j4cALaXVJIYTYOF3qszyVbxTj4kS1s,82
|
1775
|
-
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=
|
1775
|
+
vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=cW0fgmferJVm6LctqC5kCFu4Qg9udMQEb0IISLS7CTo,13795
|
1776
1776
|
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1777
|
-
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py,sha256=
|
1777
|
+
vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py,sha256=Hk_u2IxLIeeqL_s0RTgoyL5QGYwY9VllKT8z5_JHiDU,24956
|
1778
1778
|
vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py,sha256=0a40fkkZkFMmZN0CsWf6EP_y1H6x36EGa3WcfVNyOsM,9797
|
1779
1779
|
vellum/workflows/nodes/displayable/bases/search_node.py,sha256=9TtFn6oNpEkpCL59QdBViUe4WPjcITajbiS7EOjOGag,6114
|
1780
1780
|
vellum/workflows/nodes/displayable/bases/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1781
1781
|
vellum/workflows/nodes/displayable/bases/tests/test_utils.py,sha256=eqdqbKNRWVMDPevgwLg1i6YK0g4L4bCy-7xCBN5yYZI,3156
|
1782
1782
|
vellum/workflows/nodes/displayable/bases/types.py,sha256=C37B2Qh2YP7s7pUjd-EYKc2Zl1TbnCgI_mENuUSb8bo,1706
|
1783
|
-
vellum/workflows/nodes/displayable/bases/utils.py,sha256=
|
1783
|
+
vellum/workflows/nodes/displayable/bases/utils.py,sha256=X1YSPmbBlxDrTAw6dy2-9HrIG8Vb_J-2k1lP3i-SOsk,6951
|
1784
1784
|
vellum/workflows/nodes/displayable/code_execution_node/__init__.py,sha256=0FLWMMktpzSnmBMizQglBpcPrP80fzVsoJwJgf822Cg,76
|
1785
1785
|
vellum/workflows/nodes/displayable/code_execution_node/node.py,sha256=cCpZPna1Exw060KlI8j3oMCfru1GCzUFJz9ucWdcZVM,10311
|
1786
1786
|
vellum/workflows/nodes/displayable/code_execution_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1787
1787
|
vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1788
1788
|
vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/main.py,sha256=5QsbmkzSlSbcbWTG_JmIqcP-JNJzOPTKxGzdHos19W4,79
|
1789
1789
|
vellum/workflows/nodes/displayable/code_execution_node/tests/test_node.py,sha256=0lxmU-XXie6qu35qAEfZJ3vKZ1XGvWV4eq9y2RMelOE,38521
|
1790
|
-
vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256=
|
1790
|
+
vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256=GxSjRBiH8kNg2dXUVTtnX47fqPIFoGHxRB4ySU6uVPk,3225
|
1791
1791
|
vellum/workflows/nodes/displayable/conditional_node/__init__.py,sha256=AS_EIqFdU1F9t8aLmbZU-rLh9ry6LCJ0uj0D8F0L5Uw,72
|
1792
1792
|
vellum/workflows/nodes/displayable/conditional_node/node.py,sha256=71ZUNfTiD7t2Kai2ypw0tmv1lSf1brQaHAQD-SeUrGE,1101
|
1793
1793
|
vellum/workflows/nodes/displayable/conftest.py,sha256=K2kLM2JGAfcrmmd92u8DXInUO5klFdggPWblg5RVcx4,5729
|
@@ -1801,7 +1801,7 @@ vellum/workflows/nodes/displayable/guardrail_node/test_node.py,sha256=SAGv6hSFcB
|
|
1801
1801
|
vellum/workflows/nodes/displayable/guardrail_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1802
1802
|
vellum/workflows/nodes/displayable/guardrail_node/tests/test_node.py,sha256=X2pd6TI8miYxIa7rgvs1pHTEreyWcf77EyR0_Jsa700,2055
|
1803
1803
|
vellum/workflows/nodes/displayable/inline_prompt_node/__init__.py,sha256=gSUOoEZLlrx35-tQhSAd3An8WDwBqyiQh-sIebLU9wU,74
|
1804
|
-
vellum/workflows/nodes/displayable/inline_prompt_node/node.py,sha256=
|
1804
|
+
vellum/workflows/nodes/displayable/inline_prompt_node/node.py,sha256=0O1dksk0h6-V-Mp5_yTuU3PFrUpLIgsqVMTP8mxTryU,2227
|
1805
1805
|
vellum/workflows/nodes/displayable/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1806
1806
|
vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py,sha256=bBHs90mV5SZ3rJPAL0wx4WWyawUA406LgMPOdvpZC_A,10923
|
1807
1807
|
vellum/workflows/nodes/displayable/merge_node/__init__.py,sha256=J8IC08dSH7P76wKlNuxe1sn7toNGtSQdFirUbtPDEs0,60
|
@@ -1809,7 +1809,7 @@ vellum/workflows/nodes/displayable/merge_node/node.py,sha256=nZtGGVAvY4fvGg8vwV6
|
|
1809
1809
|
vellum/workflows/nodes/displayable/note_node/__init__.py,sha256=KWA3P4fyYJ-fOTky8qNGlcOotQ-HeHJ9AjZt6mRQmCE,58
|
1810
1810
|
vellum/workflows/nodes/displayable/note_node/node.py,sha256=sIN1VBQ7zeT3GhN0kupXbFfdpvgedWV79k4woJNp5IQ,394
|
1811
1811
|
vellum/workflows/nodes/displayable/prompt_deployment_node/__init__.py,sha256=krX1Hds-TSVYZsx0wJFX4wsAKkEFYOX1ifwRGiIM-EA,82
|
1812
|
-
vellum/workflows/nodes/displayable/prompt_deployment_node/node.py,sha256=
|
1812
|
+
vellum/workflows/nodes/displayable/prompt_deployment_node/node.py,sha256=XeBn6d3ce-RJuUiTwpDKUKUJvcYLQw61YufpIGVWPHY,2641
|
1813
1813
|
vellum/workflows/nodes/displayable/prompt_deployment_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1814
1814
|
vellum/workflows/nodes/displayable/prompt_deployment_node/tests/test_node.py,sha256=c_nuuqrwiIjgj4qIbVypfDuOc-3TlgO6CbXFqQl2Nqw,19725
|
1815
1815
|
vellum/workflows/nodes/displayable/search_node/__init__.py,sha256=hpBpvbrDYf43DElRZFLzieSn8weXiwNiiNOJurERQbs,62
|
@@ -1841,7 +1841,7 @@ vellum/workflows/nodes/mocks.py,sha256=a1FjWEIocseMfjzM-i8DNozpUsaW0IONRpZmXBoWl
|
|
1841
1841
|
vellum/workflows/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1842
1842
|
vellum/workflows/nodes/tests/test_mocks.py,sha256=mfPvrs75PKcsNsbJLQAN6PDFoVqs9TmQxpdyFKDdO60,7837
|
1843
1843
|
vellum/workflows/nodes/tests/test_utils.py,sha256=OPVZo9yi8qt0rVqayKhfgh4Hk-dVdIzqfbS89fDhRiE,4913
|
1844
|
-
vellum/workflows/nodes/utils.py,sha256=
|
1844
|
+
vellum/workflows/nodes/utils.py,sha256=CwDobM6T4Whm1B0cekPAIj7pdSxbFGRxx_BqgxZrimg,10265
|
1845
1845
|
vellum/workflows/outputs/__init__.py,sha256=AyZ4pRh_ACQIGvkf0byJO46EDnSix1ZCAXfvh-ms1QE,94
|
1846
1846
|
vellum/workflows/outputs/base.py,sha256=PUn0zhGzYCSZL34JXtXg9zALlXS_cqxZldLilPxDzb8,9614
|
1847
1847
|
vellum/workflows/ports/__init__.py,sha256=bZuMt-R7z5bKwpu4uPW7LlJeePOQWmCcDSXe5frUY5g,101
|
@@ -1880,7 +1880,7 @@ vellum/workflows/tests/test_undefined.py,sha256=zMCVliCXVNLrlC6hEGyOWDnQADJ2g83y
|
|
1880
1880
|
vellum/workflows/types/__init__.py,sha256=KxUTMBGzuRCfiMqzzsykOeVvrrkaZmTTo1a7SLu8gRM,68
|
1881
1881
|
vellum/workflows/types/code_execution_node_wrappers.py,sha256=3MNIoFZKzVzNS5qFLVuDwMV17QJw72zo7NRf52yMq5A,3074
|
1882
1882
|
vellum/workflows/types/core.py,sha256=TggDVs2lVya33xvu374EDhMC1b7RRlAAs0zWLaF46BA,1385
|
1883
|
-
vellum/workflows/types/definition.py,sha256=
|
1883
|
+
vellum/workflows/types/definition.py,sha256=2vq3uGT-m994zRcla0yTUsMiPLKSDuzEZs7H6U9QbiE,4993
|
1884
1884
|
vellum/workflows/types/generics.py,sha256=8jptbEx1fnJV0Lhj0MpCJOT6yNiEWeTOYOwrEAb5CRU,1576
|
1885
1885
|
vellum/workflows/types/stack.py,sha256=h7NE0vXR7l9DevFBIzIAk1Zh59K-kECQtDTKOUunwMY,1314
|
1886
1886
|
vellum/workflows/types/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1888,12 +1888,12 @@ vellum/workflows/types/tests/test_definition.py,sha256=rvDYjdJ1rvAv0qHBN7i7s-_WA
|
|
1888
1888
|
vellum/workflows/types/tests/test_utils.py,sha256=UnZog59tR577mVwqZRqqWn2fScoOU1H6up0EzS8zYhw,2536
|
1889
1889
|
vellum/workflows/types/utils.py,sha256=mTctHITBybpt4855x32oCKALBEcMNLn-9cCmfEKgJHQ,6498
|
1890
1890
|
vellum/workflows/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1891
|
-
vellum/workflows/utils/functions.py,sha256=
|
1891
|
+
vellum/workflows/utils/functions.py,sha256=_mJ7vGxHLIByPbfMpDVKsWVEUGlCof1Bc2aZefF56Ns,8967
|
1892
1892
|
vellum/workflows/utils/hmac.py,sha256=JJCczc6pyV6DuE1Oa0QVfYPUN_of3zEYmGFib3OZnrE,1135
|
1893
1893
|
vellum/workflows/utils/names.py,sha256=QLUqfJ1tmSEeUwBKTTiv_Qk3QGbInC2RSmlXfGXc8Wo,380
|
1894
1894
|
vellum/workflows/utils/pydantic_schema.py,sha256=eR_bBtY-T0pttJP-ARwagSdCOnwPUtiT3cegm2lzDTQ,1310
|
1895
1895
|
vellum/workflows/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1896
|
-
vellum/workflows/utils/tests/test_functions.py,sha256=
|
1896
|
+
vellum/workflows/utils/tests/test_functions.py,sha256=TlNhD0OBJ-aeYn4qUqmApuajkx9sJx0lIQRMfT8Xf0w,23688
|
1897
1897
|
vellum/workflows/utils/tests/test_names.py,sha256=aOqpyvMsOEK_9mg_-yaNxQDW7QQfwqsYs37PseyLhxw,402
|
1898
1898
|
vellum/workflows/utils/tests/test_uuids.py,sha256=i77ABQ0M3S-aFLzDXHJq_yr5FPkJEWCMBn1HJ3DObrE,437
|
1899
1899
|
vellum/workflows/utils/tests/test_vellum_variables.py,sha256=vbnKgm41aB5OXlO-ZIPbhQ6xDiZkT8KMxCLqz4zocWY,1791
|
@@ -1906,8 +1906,8 @@ vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnad
|
|
1906
1906
|
vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1907
1907
|
vellum/workflows/workflows/tests/test_base_workflow.py,sha256=ptMntHzVyy8ZuzNgeTuk7hREgKQ5UBdgq8VJFSGaW4Y,20832
|
1908
1908
|
vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
|
1909
|
-
vellum_ai-1.2.
|
1910
|
-
vellum_ai-1.2.
|
1911
|
-
vellum_ai-1.2.
|
1912
|
-
vellum_ai-1.2.
|
1913
|
-
vellum_ai-1.2.
|
1909
|
+
vellum_ai-1.2.4.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
1910
|
+
vellum_ai-1.2.4.dist-info/METADATA,sha256=5gsVuDhKzbBpbW7awdKuaGhzXGg2IBxDeY66boLv0ns,5547
|
1911
|
+
vellum_ai-1.2.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
1912
|
+
vellum_ai-1.2.4.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
|
1913
|
+
vellum_ai-1.2.4.dist-info/RECORD,,
|
vellum_cli/__init__.py
CHANGED
@@ -68,6 +68,7 @@ with the provided module or be available for use. The Workflow Sandbox must also
|
|
68
68
|
@click.option("--deployment-name", type=str, help="Unique name for the Deployment")
|
69
69
|
@click.option("--deployment-description", type=str, help="Description for the Deployment")
|
70
70
|
@click.option("--release-tag", help="Release Tag for the Deployment", multiple=True)
|
71
|
+
@click.option("--release-description", type=str, help="Description for the Release")
|
71
72
|
@click.option(
|
72
73
|
"--dry-run",
|
73
74
|
is_flag=True,
|
@@ -87,6 +88,7 @@ def workflows_push(
|
|
87
88
|
deployment_name: Optional[str],
|
88
89
|
deployment_description: Optional[str],
|
89
90
|
release_tag: Optional[List[str]],
|
91
|
+
release_description: Optional[str],
|
90
92
|
dry_run: Optional[bool],
|
91
93
|
strict: Optional[bool],
|
92
94
|
workspace: Optional[str],
|
@@ -104,6 +106,7 @@ def workflows_push(
|
|
104
106
|
deployment_name=deployment_name,
|
105
107
|
deployment_description=deployment_description,
|
106
108
|
release_tags=release_tag,
|
109
|
+
release_description=release_description,
|
107
110
|
dry_run=dry_run,
|
108
111
|
strict=strict,
|
109
112
|
workspace=workspace,
|
@@ -118,6 +121,7 @@ def workflows_push(
|
|
118
121
|
@click.option("--deployment-name", type=str, help="Unique name for the Deployment")
|
119
122
|
@click.option("--deployment-description", type=str, help="Description for the Deployment")
|
120
123
|
@click.option("--release-tag", help="Release Tag for the Deployment", multiple=True)
|
124
|
+
@click.option("--release-description", type=str, help="Description for the Release")
|
121
125
|
@click.option(
|
122
126
|
"--dry-run",
|
123
127
|
is_flag=True,
|
@@ -137,6 +141,7 @@ def push_module(
|
|
137
141
|
deployment_name: Optional[str],
|
138
142
|
deployment_description: Optional[str],
|
139
143
|
release_tag: Optional[List[str]],
|
144
|
+
release_description: Optional[str],
|
140
145
|
dry_run: Optional[bool],
|
141
146
|
strict: Optional[bool],
|
142
147
|
workspace: Optional[str],
|
@@ -152,6 +157,7 @@ def push_module(
|
|
152
157
|
deployment_name=deployment_name,
|
153
158
|
deployment_description=deployment_description,
|
154
159
|
release_tags=release_tag,
|
160
|
+
release_description=release_description,
|
155
161
|
dry_run=dry_run,
|
156
162
|
strict=strict,
|
157
163
|
workspace=workspace,
|
vellum_cli/config.py
CHANGED
@@ -36,6 +36,7 @@ class WorkflowDeploymentConfig(UniversalBaseModel):
|
|
36
36
|
name: Optional[str] = None
|
37
37
|
description: Optional[str] = None
|
38
38
|
release_tags: Optional[List[str]] = None
|
39
|
+
release_description: Optional[str] = None
|
39
40
|
|
40
41
|
def merge(self, other: "WorkflowDeploymentConfig") -> "WorkflowDeploymentConfig":
|
41
42
|
return WorkflowDeploymentConfig(
|
@@ -44,6 +45,7 @@ class WorkflowDeploymentConfig(UniversalBaseModel):
|
|
44
45
|
name=self.name or other.name,
|
45
46
|
description=self.description or other.description,
|
46
47
|
release_tags=self.release_tags or other.release_tags,
|
48
|
+
release_description=self.release_description or other.release_description,
|
47
49
|
)
|
48
50
|
|
49
51
|
|
vellum_cli/push.py
CHANGED
@@ -28,6 +28,7 @@ def push_command(
|
|
28
28
|
deployment_name: Optional[str] = None,
|
29
29
|
deployment_description: Optional[str] = None,
|
30
30
|
release_tags: Optional[List[str]] = None,
|
31
|
+
release_description: Optional[str] = None,
|
31
32
|
dry_run: Optional[bool] = None,
|
32
33
|
strict: Optional[bool] = None,
|
33
34
|
workspace: Optional[str] = None,
|
@@ -142,6 +143,7 @@ def push_command(
|
|
142
143
|
name=deployment_name or cli_deployment_config.name or to_kebab_case(module_name),
|
143
144
|
description=deployment_description or cli_deployment_config.description,
|
144
145
|
release_tags=release_tags or cli_deployment_config.release_tags,
|
146
|
+
release_description=release_description or cli_deployment_config.release_description,
|
145
147
|
)
|
146
148
|
except ValidationError as e:
|
147
149
|
for error in e.errors():
|
@@ -286,6 +288,7 @@ Visit at: {base_url}/workflow-sandboxes/{response.workflow_sandbox_id}"""
|
|
286
288
|
name=deployment_config.name if deploy else None,
|
287
289
|
description=deployment_config.description if deploy else None,
|
288
290
|
release_tags=deployment_config.release_tags if deploy else None,
|
291
|
+
release_description=getattr(deployment_config, "release_description", None) if deploy else None,
|
289
292
|
)
|
290
293
|
workflow_config.deployments.append(stored_deployment_config)
|
291
294
|
|
vellum_cli/tests/test_pull.py
CHANGED
@@ -393,6 +393,7 @@ def test_pull__workflow_deployment_with_no_config(vellum_client):
|
|
393
393
|
"name": "my-deployment",
|
394
394
|
"description": None,
|
395
395
|
"release_tags": None,
|
396
|
+
"release_description": None,
|
396
397
|
}
|
397
398
|
],
|
398
399
|
"container_image_tag": None,
|
@@ -641,6 +642,7 @@ def test_pull__sandbox_id_with_other_workflow_deployment_in_lock(vellum_client,
|
|
641
642
|
"name": None,
|
642
643
|
"description": None,
|
643
644
|
"release_tags": None,
|
645
|
+
"release_description": None,
|
644
646
|
},
|
645
647
|
],
|
646
648
|
"container_image_name": None,
|
vellum_cli/tests/test_push.py
CHANGED
@@ -1042,6 +1042,45 @@ def test_push__deploy_with_release_tags_success(mock_module, vellum_client):
|
|
1042
1042
|
assert "Updated vellum.lock.json file." in result.output
|
1043
1043
|
|
1044
1044
|
|
1045
|
+
@pytest.mark.usefixtures("info_log_level")
|
1046
|
+
def test_push__deploy_with_release_description_success(mock_module, vellum_client):
|
1047
|
+
# GIVEN a single workflow configured
|
1048
|
+
temp_dir = mock_module.temp_dir
|
1049
|
+
module = mock_module.module
|
1050
|
+
|
1051
|
+
# AND a workflow exists in the module successfully
|
1052
|
+
_ensure_workflow_py(temp_dir, module)
|
1053
|
+
|
1054
|
+
# AND the push API call returns successfully
|
1055
|
+
workflow_deployment_id = str(uuid4())
|
1056
|
+
vellum_client.workflows.push.return_value = WorkflowPushResponse(
|
1057
|
+
workflow_sandbox_id=str(uuid4()),
|
1058
|
+
workflow_deployment_id=workflow_deployment_id,
|
1059
|
+
)
|
1060
|
+
|
1061
|
+
# WHEN calling `vellum workflows push` with --deploy and --release-description
|
1062
|
+
runner = CliRunner()
|
1063
|
+
result = runner.invoke(
|
1064
|
+
cli_main, ["workflows", "push", module, "--deploy", "--release-description", "This is a test release"]
|
1065
|
+
)
|
1066
|
+
|
1067
|
+
# THEN it should succeed
|
1068
|
+
assert result.exit_code == 0, result.output
|
1069
|
+
|
1070
|
+
# AND we should have called the push API with the correct deployment config
|
1071
|
+
vellum_client.workflows.push.assert_called_once()
|
1072
|
+
call_args = vellum_client.workflows.push.call_args.kwargs
|
1073
|
+
|
1074
|
+
# AND the deployment_config should contain the release description
|
1075
|
+
deployment_config_str = call_args["deployment_config"]
|
1076
|
+
deployment_config = json.loads(deployment_config_str)
|
1077
|
+
assert deployment_config["release_description"] == "This is a test release"
|
1078
|
+
|
1079
|
+
# AND should show success message
|
1080
|
+
assert "Successfully pushed" in result.output
|
1081
|
+
assert "Updated vellum.lock.json file." in result.output
|
1082
|
+
|
1083
|
+
|
1045
1084
|
def test_push__deploy_stores_deployment_config_in_lock_file(mock_module, vellum_client):
|
1046
1085
|
# GIVEN a single workflow
|
1047
1086
|
temp_dir = mock_module.temp_dir
|
@@ -191,6 +191,7 @@ def test_serialize_node__tool_calling_node__mcp_server_api_key():
|
|
191
191
|
{
|
192
192
|
"type": "MCP_SERVER",
|
193
193
|
"name": "my-mcp-server",
|
194
|
+
"description": "",
|
194
195
|
"url": "https://my-mcp-server.com",
|
195
196
|
"authorization_type": "API_KEY",
|
196
197
|
"bearer_token_value": None,
|
@@ -243,6 +244,7 @@ def test_serialize_node__tool_calling_node__mcp_server_no_authorization():
|
|
243
244
|
{
|
244
245
|
"type": "MCP_SERVER",
|
245
246
|
"name": "my-mcp-server",
|
247
|
+
"description": "",
|
246
248
|
"url": "https://my-mcp-server.com",
|
247
249
|
"authorization_type": None,
|
248
250
|
"bearer_token_value": None,
|
File without changes
|
File without changes
|
File without changes
|