vellum-ai 0.14.71__py3-none-any.whl → 0.14.72__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 +1 -1
- vellum/plugins/vellum_mypy.py +1 -1
- vellum/workflows/events/__init__.py +2 -0
- vellum/workflows/events/stream.py +28 -0
- vellum/workflows/events/workflow.py +3 -2
- vellum/workflows/nodes/experimental/tool_calling_node/node.py +1 -1
- vellum/workflows/nodes/experimental/tool_calling_node/utils.py +2 -2
- vellum/workflows/runner/runner.py +21 -3
- vellum/workflows/utils/functions.py +55 -1
- vellum/workflows/utils/tests/test_functions.py +151 -1
- vellum/workflows/utils/tests/test_vellum_variables.py +25 -1
- vellum/workflows/utils/vellum_variables.py +30 -0
- vellum/workflows/workflows/base.py +11 -5
- {vellum_ai-0.14.71.dist-info → vellum_ai-0.14.72.dist-info}/METADATA +1 -1
- {vellum_ai-0.14.71.dist-info → vellum_ai-0.14.72.dist-info}/RECORD +23 -22
- vellum_cli/image_push.py +1 -5
- vellum_cli/push.py +7 -0
- vellum_cli/tests/test_image_push.py +1 -2
- vellum_cli/tests/test_push.py +33 -2
- vellum_ee/workflows/display/nodes/utils.py +2 -2
- {vellum_ai-0.14.71.dist-info → vellum_ai-0.14.72.dist-info}/LICENSE +0 -0
- {vellum_ai-0.14.71.dist-info → vellum_ai-0.14.72.dist-info}/WHEEL +0 -0
- {vellum_ai-0.14.71.dist-info → vellum_ai-0.14.72.dist-info}/entry_points.txt +0 -0
@@ -18,7 +18,7 @@ class BaseClientWrapper:
|
|
18
18
|
headers: typing.Dict[str, str] = {
|
19
19
|
"X-Fern-Language": "Python",
|
20
20
|
"X-Fern-SDK-Name": "vellum-ai",
|
21
|
-
"X-Fern-SDK-Version": "0.14.
|
21
|
+
"X-Fern-SDK-Version": "0.14.72",
|
22
22
|
}
|
23
23
|
headers["X-API-KEY"] = self.api_key
|
24
24
|
return headers
|
vellum/plugins/vellum_mypy.py
CHANGED
@@ -573,7 +573,7 @@ class VellumMypyPlugin(Plugin):
|
|
573
573
|
alias_target = alias.target
|
574
574
|
if (
|
575
575
|
not isinstance(alias_target, Instance)
|
576
|
-
or not _is_subclass(alias_target.type, "
|
576
|
+
or not _is_subclass(alias_target.type, "vellum.workflows.events.stream.WorkflowEventGenerator")
|
577
577
|
or not alias_target.args
|
578
578
|
):
|
579
579
|
return ctx.default_return_type
|
@@ -5,6 +5,7 @@ from .node import (
|
|
5
5
|
NodeExecutionRejectedEvent,
|
6
6
|
NodeExecutionStreamingEvent,
|
7
7
|
)
|
8
|
+
from .stream import WorkflowEventGenerator
|
8
9
|
from .workflow import (
|
9
10
|
WorkflowEvent,
|
10
11
|
WorkflowEventStream,
|
@@ -26,4 +27,5 @@ __all__ = [
|
|
26
27
|
"WorkflowExecutionStreamingEvent",
|
27
28
|
"WorkflowEvent",
|
28
29
|
"WorkflowEventStream",
|
30
|
+
"WorkflowEventGenerator",
|
29
31
|
]
|
@@ -0,0 +1,28 @@
|
|
1
|
+
from uuid import UUID
|
2
|
+
from typing import Generator, Generic, Iterator, TypeVar
|
3
|
+
|
4
|
+
EventType = TypeVar("EventType")
|
5
|
+
|
6
|
+
|
7
|
+
class WorkflowEventGenerator(Generic[EventType]):
|
8
|
+
"""
|
9
|
+
Generic wrapper for event streams that exposes span_id as a top-level property
|
10
|
+
while maintaining iterator compatibility.
|
11
|
+
"""
|
12
|
+
|
13
|
+
def __init__(self, event_generator: Generator[EventType, None, None], span_id: UUID):
|
14
|
+
self._event_generator = event_generator
|
15
|
+
self._span_id = span_id
|
16
|
+
|
17
|
+
@property
|
18
|
+
def span_id(self) -> UUID:
|
19
|
+
"""The span_id associated with this workflow stream."""
|
20
|
+
return self._span_id
|
21
|
+
|
22
|
+
def __iter__(self) -> Iterator[EventType]:
|
23
|
+
"""Return self to make this object iterable."""
|
24
|
+
return self
|
25
|
+
|
26
|
+
def __next__(self) -> EventType:
|
27
|
+
"""Get the next event from the underlying generator."""
|
28
|
+
return next(self._event_generator)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from uuid import UUID
|
2
|
-
from typing import TYPE_CHECKING, Any, Dict,
|
2
|
+
from typing import TYPE_CHECKING, Any, Dict, Generic, Iterable, Literal, Optional, Type, Union
|
3
3
|
from typing_extensions import TypeGuard
|
4
4
|
|
5
5
|
from pydantic import field_serializer
|
@@ -19,6 +19,7 @@ from .node import (
|
|
19
19
|
NodeExecutionResumedEvent,
|
20
20
|
NodeExecutionStreamingEvent,
|
21
21
|
)
|
22
|
+
from .stream import WorkflowEventGenerator
|
22
23
|
from .types import BaseEvent, default_serializer
|
23
24
|
|
24
25
|
if TYPE_CHECKING:
|
@@ -193,7 +194,7 @@ WorkflowEvent = Union[
|
|
193
194
|
WorkflowExecutionSnapshottedEvent,
|
194
195
|
]
|
195
196
|
|
196
|
-
WorkflowEventStream =
|
197
|
+
WorkflowEventStream = WorkflowEventGenerator[WorkflowEvent]
|
197
198
|
|
198
199
|
WorkflowExecutionEvent = Union[
|
199
200
|
WorkflowExecutionInitiatedEvent,
|
@@ -110,7 +110,7 @@ class ToolCallingNode(BaseNode):
|
|
110
110
|
|
111
111
|
# Get configuration for this function
|
112
112
|
config = {}
|
113
|
-
if self.function_configs and function.__name__ in self.function_configs:
|
113
|
+
if callable(function) and self.function_configs and function.__name__ in self.function_configs:
|
114
114
|
config = self.function_configs[function.__name__]
|
115
115
|
|
116
116
|
packages = config.get("packages", None)
|
@@ -145,7 +145,7 @@ def create_function_node(
|
|
145
145
|
"""
|
146
146
|
if is_workflow_class(function):
|
147
147
|
# Create a class-level wrapper that calls the original function
|
148
|
-
def
|
148
|
+
def execute_inline_workflow_function(self) -> BaseNode.Outputs:
|
149
149
|
outputs = self.state.meta.node_outputs.get(tool_router_node.Outputs.text)
|
150
150
|
|
151
151
|
outputs = json.loads(outputs)
|
@@ -181,7 +181,7 @@ def create_function_node(
|
|
181
181
|
f"InlineWorkflowNode_{function.__name__}",
|
182
182
|
(FunctionNode,),
|
183
183
|
{
|
184
|
-
"run":
|
184
|
+
"run": execute_inline_workflow_function,
|
185
185
|
"__module__": __name__,
|
186
186
|
},
|
187
187
|
)
|
@@ -5,7 +5,21 @@ import logging
|
|
5
5
|
from queue import Empty, Queue
|
6
6
|
from threading import Event as ThreadingEvent, Thread
|
7
7
|
from uuid import UUID, uuid4
|
8
|
-
from typing import
|
8
|
+
from typing import (
|
9
|
+
TYPE_CHECKING,
|
10
|
+
Any,
|
11
|
+
Dict,
|
12
|
+
Generator,
|
13
|
+
Generic,
|
14
|
+
Iterable,
|
15
|
+
Iterator,
|
16
|
+
Optional,
|
17
|
+
Sequence,
|
18
|
+
Set,
|
19
|
+
Tuple,
|
20
|
+
Type,
|
21
|
+
Union,
|
22
|
+
)
|
9
23
|
|
10
24
|
from vellum.workflows.constants import undefined
|
11
25
|
from vellum.workflows.context import ExecutionContext, execution_context, get_execution_context
|
@@ -17,7 +31,7 @@ from vellum.workflows.events import (
|
|
17
31
|
NodeExecutionRejectedEvent,
|
18
32
|
NodeExecutionStreamingEvent,
|
19
33
|
WorkflowEvent,
|
20
|
-
|
34
|
+
WorkflowEventGenerator,
|
21
35
|
WorkflowExecutionFulfilledEvent,
|
22
36
|
WorkflowExecutionInitiatedEvent,
|
23
37
|
WorkflowExecutionRejectedEvent,
|
@@ -31,6 +45,7 @@ from vellum.workflows.events.node import (
|
|
31
45
|
)
|
32
46
|
from vellum.workflows.events.types import BaseEvent, NodeParentContext, ParentContext, WorkflowParentContext
|
33
47
|
from vellum.workflows.events.workflow import (
|
48
|
+
WorkflowEventStream,
|
34
49
|
WorkflowExecutionFulfilledBody,
|
35
50
|
WorkflowExecutionInitiatedBody,
|
36
51
|
WorkflowExecutionPausedBody,
|
@@ -730,7 +745,7 @@ class WorkflowRunner(Generic[StateType]):
|
|
730
745
|
return event.workflow_definition == self.workflow.__class__
|
731
746
|
return False
|
732
747
|
|
733
|
-
def
|
748
|
+
def _generate_events(self) -> Generator[WorkflowEvent, None, None]:
|
734
749
|
background_thread = Thread(
|
735
750
|
target=self._run_background_thread,
|
736
751
|
name=f"{self.workflow.__class__.__name__}.background_thread",
|
@@ -788,3 +803,6 @@ class WorkflowRunner(Generic[StateType]):
|
|
788
803
|
|
789
804
|
self._background_thread_queue.put(None)
|
790
805
|
cancel_thread_kill_switch.set()
|
806
|
+
|
807
|
+
def stream(self) -> WorkflowEventStream:
|
808
|
+
return WorkflowEventGenerator(self._generate_events(), self._initial_state.meta.span_id)
|
@@ -1,12 +1,14 @@
|
|
1
1
|
import dataclasses
|
2
2
|
import inspect
|
3
|
-
from typing import TYPE_CHECKING, Any, Callable, Optional, Type, Union, get_args, get_origin
|
3
|
+
from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Type, Union, get_args, get_origin
|
4
4
|
|
5
5
|
from pydantic import BaseModel
|
6
6
|
from pydantic_core import PydanticUndefined
|
7
7
|
from pydash import snake_case
|
8
8
|
|
9
|
+
from vellum import Vellum
|
9
10
|
from vellum.client.types.function_definition import FunctionDefinition
|
11
|
+
from vellum.workflows.utils.vellum_variables import vellum_variable_type_to_openapi_type
|
10
12
|
|
11
13
|
if TYPE_CHECKING:
|
12
14
|
from vellum.workflows.workflows.base import BaseWorkflow
|
@@ -86,6 +88,19 @@ def _compile_default_value(default: Any) -> Any:
|
|
86
88
|
return default
|
87
89
|
|
88
90
|
|
91
|
+
def _compile_deployment_workflow_input(input_var: Any) -> dict[str, Any]:
|
92
|
+
"""
|
93
|
+
Converts a deployment workflow input variable to a JSON schema type definition.
|
94
|
+
"""
|
95
|
+
primitive_type = vellum_variable_type_to_openapi_type(input_var.type)
|
96
|
+
input_schema = {"type": primitive_type}
|
97
|
+
|
98
|
+
if input_var.default is not None:
|
99
|
+
input_schema["default"] = input_var.default.value
|
100
|
+
|
101
|
+
return input_schema
|
102
|
+
|
103
|
+
|
89
104
|
def compile_function_definition(function: Callable) -> FunctionDefinition:
|
90
105
|
"""
|
91
106
|
Converts a Python function into our Vellum-native FunctionDefinition type.
|
@@ -151,3 +166,42 @@ def compile_workflow_function_definition(workflow_class: Type["BaseWorkflow"]) -
|
|
151
166
|
description=workflow_class.__doc__,
|
152
167
|
parameters=parameters,
|
153
168
|
)
|
169
|
+
|
170
|
+
|
171
|
+
def compile_deployment_workflow_function_definition(
|
172
|
+
deployment_config: Dict[str, str],
|
173
|
+
vellum_client: Vellum,
|
174
|
+
) -> FunctionDefinition:
|
175
|
+
"""
|
176
|
+
Converts a deployment workflow config into our Vellum-native FunctionDefinition type.
|
177
|
+
|
178
|
+
Args:
|
179
|
+
deployment_config: Dict with 'deployment' and 'release_tag' keys
|
180
|
+
vellum_client: Vellum client instance
|
181
|
+
"""
|
182
|
+
deployment = deployment_config["deployment"]
|
183
|
+
release_tag = deployment_config["release_tag"]
|
184
|
+
|
185
|
+
workflow_deployment_release = vellum_client.release_reviews.retrieve_workflow_deployment_release(
|
186
|
+
deployment, release_tag
|
187
|
+
)
|
188
|
+
|
189
|
+
input_variables = workflow_deployment_release.workflow_version.input_variables
|
190
|
+
description = workflow_deployment_release.description
|
191
|
+
|
192
|
+
properties = {}
|
193
|
+
required = []
|
194
|
+
|
195
|
+
for input_var in input_variables:
|
196
|
+
properties[input_var.key] = _compile_deployment_workflow_input(input_var)
|
197
|
+
|
198
|
+
if input_var.required and input_var.default is None:
|
199
|
+
required.append(input_var.key)
|
200
|
+
|
201
|
+
parameters = {"type": "object", "properties": properties, "required": required}
|
202
|
+
|
203
|
+
return FunctionDefinition(
|
204
|
+
name=deployment,
|
205
|
+
description=description,
|
206
|
+
parameters=parameters,
|
207
|
+
)
|
@@ -1,14 +1,21 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
|
+
from unittest.mock import Mock
|
2
3
|
from typing import Dict, List, Optional, Union
|
3
4
|
|
4
5
|
from pydantic import BaseModel
|
5
6
|
|
6
7
|
from vellum.client.types.function_definition import FunctionDefinition
|
8
|
+
from vellum.client.types.string_vellum_value import StringVellumValue
|
9
|
+
from vellum.client.types.vellum_variable import VellumVariable
|
7
10
|
from vellum.workflows import BaseWorkflow
|
8
11
|
from vellum.workflows.inputs.base import BaseInputs
|
9
12
|
from vellum.workflows.nodes.bases.base import BaseNode
|
10
13
|
from vellum.workflows.state.base import BaseState
|
11
|
-
from vellum.workflows.utils.functions import
|
14
|
+
from vellum.workflows.utils.functions import (
|
15
|
+
compile_deployment_workflow_function_definition,
|
16
|
+
compile_function_definition,
|
17
|
+
compile_workflow_function_definition,
|
18
|
+
)
|
12
19
|
|
13
20
|
|
14
21
|
def test_compile_function_definition__just_name():
|
@@ -431,3 +438,146 @@ def test_compile_workflow_function_definition__optionals():
|
|
431
438
|
"required": ["a", "b", "c"],
|
432
439
|
},
|
433
440
|
)
|
441
|
+
|
442
|
+
|
443
|
+
def test_compile_deployment_workflow_function_definition__just_name():
|
444
|
+
# GIVEN a mock Vellum client and deployment
|
445
|
+
mock_client = Mock()
|
446
|
+
mock_release = Mock()
|
447
|
+
mock_release.workflow_version.input_variables = []
|
448
|
+
mock_release.description = "This is a test deployment"
|
449
|
+
mock_client.release_reviews.retrieve_workflow_deployment_release.return_value = mock_release
|
450
|
+
|
451
|
+
deployment_config = {"deployment": "my_deployment", "release_tag": "latest"}
|
452
|
+
|
453
|
+
# WHEN compiling the deployment workflow function
|
454
|
+
compiled_function = compile_deployment_workflow_function_definition(deployment_config, mock_client)
|
455
|
+
|
456
|
+
# THEN it should return the compiled function definition (same structure as function test)
|
457
|
+
assert compiled_function == FunctionDefinition(
|
458
|
+
name="my_deployment",
|
459
|
+
description="This is a test deployment",
|
460
|
+
parameters={"type": "object", "properties": {}, "required": []},
|
461
|
+
)
|
462
|
+
|
463
|
+
|
464
|
+
def test_compile_deployment_workflow_function_definition__all_args():
|
465
|
+
# GIVEN a mock Vellum client and deployment
|
466
|
+
mock_client = Mock()
|
467
|
+
mock_release = Mock()
|
468
|
+
|
469
|
+
mock_inputs = []
|
470
|
+
for key, vellum_type in [
|
471
|
+
("a", "STRING"),
|
472
|
+
("b", "NUMBER"),
|
473
|
+
("c", "JSON"),
|
474
|
+
("d", "CHAT_HISTORY"),
|
475
|
+
("e", "SEARCH_RESULTS"),
|
476
|
+
("f", "ERROR"),
|
477
|
+
("g", "ARRAY"),
|
478
|
+
("h", "FUNCTION_CALL"),
|
479
|
+
("i", "IMAGE"),
|
480
|
+
("j", "AUDIO"),
|
481
|
+
("k", "DOCUMENT"),
|
482
|
+
("l", "NULL"),
|
483
|
+
]:
|
484
|
+
mock_input = VellumVariable(
|
485
|
+
id=f"input_{key}",
|
486
|
+
key=key,
|
487
|
+
type=vellum_type,
|
488
|
+
required=True,
|
489
|
+
default=None,
|
490
|
+
)
|
491
|
+
mock_inputs.append(mock_input)
|
492
|
+
|
493
|
+
mock_release.workflow_version.input_variables = mock_inputs
|
494
|
+
mock_release.description = "This is a test deployment"
|
495
|
+
mock_client.release_reviews.retrieve_workflow_deployment_release.return_value = mock_release
|
496
|
+
|
497
|
+
deployment_config = {"deployment": "my_deployment", "release_tag": "latest"}
|
498
|
+
|
499
|
+
# WHEN compiling the deployment workflow function
|
500
|
+
compiled_function = compile_deployment_workflow_function_definition(deployment_config, mock_client)
|
501
|
+
|
502
|
+
# THEN it should return the compiled function definition
|
503
|
+
assert compiled_function == FunctionDefinition(
|
504
|
+
name="my_deployment",
|
505
|
+
description="This is a test deployment",
|
506
|
+
parameters={
|
507
|
+
"type": "object",
|
508
|
+
"properties": {
|
509
|
+
"a": {"type": "string"},
|
510
|
+
"b": {"type": "number"},
|
511
|
+
"c": {"type": "object"},
|
512
|
+
"d": {"type": "array"},
|
513
|
+
"e": {"type": "array"},
|
514
|
+
"f": {"type": "object"},
|
515
|
+
"g": {"type": "array"},
|
516
|
+
"h": {"type": "object"},
|
517
|
+
"i": {"type": "object"},
|
518
|
+
"j": {"type": "object"},
|
519
|
+
"k": {"type": "object"},
|
520
|
+
"l": {"type": "null"},
|
521
|
+
},
|
522
|
+
"required": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"],
|
523
|
+
},
|
524
|
+
)
|
525
|
+
|
526
|
+
|
527
|
+
def test_compile_deployment_workflow_function_definition__defaults():
|
528
|
+
# GIVEN a mock Vellum client and deployment
|
529
|
+
mock_client = Mock()
|
530
|
+
mock_release = Mock()
|
531
|
+
|
532
|
+
mock_inputs = []
|
533
|
+
|
534
|
+
mock_input_no_default = VellumVariable(
|
535
|
+
id="no_default",
|
536
|
+
key="no_default",
|
537
|
+
type="STRING",
|
538
|
+
required=True,
|
539
|
+
default=None,
|
540
|
+
)
|
541
|
+
mock_inputs.append(mock_input_no_default)
|
542
|
+
|
543
|
+
mock_input_null_default = VellumVariable(
|
544
|
+
id="null_default",
|
545
|
+
key="null_default",
|
546
|
+
type="STRING",
|
547
|
+
required=False,
|
548
|
+
default=StringVellumValue(value=None),
|
549
|
+
)
|
550
|
+
mock_inputs.append(mock_input_null_default)
|
551
|
+
|
552
|
+
mock_input_actual_default = VellumVariable(
|
553
|
+
id="actual_default",
|
554
|
+
key="actual_default",
|
555
|
+
type="STRING",
|
556
|
+
required=False,
|
557
|
+
default=StringVellumValue(value="hello world"),
|
558
|
+
)
|
559
|
+
mock_inputs.append(mock_input_actual_default)
|
560
|
+
|
561
|
+
mock_release.workflow_version.input_variables = mock_inputs
|
562
|
+
mock_release.description = "This is a test deployment"
|
563
|
+
mock_client.release_reviews.retrieve_workflow_deployment_release.return_value = mock_release
|
564
|
+
|
565
|
+
deployment_config = {"deployment": "my_deployment", "release_tag": "latest"}
|
566
|
+
|
567
|
+
# WHEN compiling the deployment workflow function
|
568
|
+
compiled_function = compile_deployment_workflow_function_definition(deployment_config, mock_client)
|
569
|
+
|
570
|
+
# THEN it should return the compiled function definition with proper default handling
|
571
|
+
assert compiled_function == FunctionDefinition(
|
572
|
+
name="my_deployment",
|
573
|
+
description="This is a test deployment",
|
574
|
+
parameters={
|
575
|
+
"type": "object",
|
576
|
+
"properties": {
|
577
|
+
"no_default": {"type": "string"},
|
578
|
+
"null_default": {"type": "string", "default": None},
|
579
|
+
"actual_default": {"type": "string", "default": "hello world"},
|
580
|
+
},
|
581
|
+
"required": ["no_default"],
|
582
|
+
},
|
583
|
+
)
|
@@ -3,7 +3,10 @@ from typing import List, Optional
|
|
3
3
|
|
4
4
|
from vellum import ChatMessage, SearchResult, VellumAudio, VellumDocument, VellumImage
|
5
5
|
from vellum.workflows.types.core import Json
|
6
|
-
from vellum.workflows.utils.vellum_variables import
|
6
|
+
from vellum.workflows.utils.vellum_variables import (
|
7
|
+
primitive_type_to_vellum_variable_type,
|
8
|
+
vellum_variable_type_to_openapi_type,
|
9
|
+
)
|
7
10
|
|
8
11
|
|
9
12
|
@pytest.mark.parametrize(
|
@@ -31,3 +34,24 @@ from vellum.workflows.utils.vellum_variables import primitive_type_to_vellum_var
|
|
31
34
|
)
|
32
35
|
def test_primitive_type_to_vellum_variable_type(type_, expected):
|
33
36
|
assert primitive_type_to_vellum_variable_type(type_) == expected
|
37
|
+
|
38
|
+
|
39
|
+
@pytest.mark.parametrize(
|
40
|
+
"vellum_type, expected",
|
41
|
+
[
|
42
|
+
("STRING", "string"),
|
43
|
+
("NUMBER", "number"),
|
44
|
+
("JSON", "object"),
|
45
|
+
("CHAT_HISTORY", "array"),
|
46
|
+
("SEARCH_RESULTS", "array"),
|
47
|
+
("ERROR", "object"),
|
48
|
+
("ARRAY", "array"),
|
49
|
+
("FUNCTION_CALL", "object"),
|
50
|
+
("IMAGE", "object"),
|
51
|
+
("AUDIO", "object"),
|
52
|
+
("DOCUMENT", "object"),
|
53
|
+
("NULL", "null"),
|
54
|
+
],
|
55
|
+
)
|
56
|
+
def test_vellum_variable_type_to_openapi_type(vellum_type, expected):
|
57
|
+
assert vellum_variable_type_to_openapi_type(vellum_type) == expected
|
@@ -78,6 +78,36 @@ def primitive_type_to_vellum_variable_type(type_: Union[Type, BaseDescriptor]) -
|
|
78
78
|
return "JSON"
|
79
79
|
|
80
80
|
|
81
|
+
def vellum_variable_type_to_openapi_type(vellum_type: VellumVariableType) -> str:
|
82
|
+
"""Converts a VellumVariableType to a JSON schema primitive type string"""
|
83
|
+
if vellum_type == "STRING":
|
84
|
+
return "string"
|
85
|
+
elif vellum_type == "NUMBER":
|
86
|
+
return "number"
|
87
|
+
elif vellum_type == "JSON":
|
88
|
+
return "object"
|
89
|
+
elif vellum_type == "CHAT_HISTORY":
|
90
|
+
return "array"
|
91
|
+
elif vellum_type == "SEARCH_RESULTS":
|
92
|
+
return "array"
|
93
|
+
elif vellum_type == "ERROR":
|
94
|
+
return "object"
|
95
|
+
elif vellum_type == "ARRAY":
|
96
|
+
return "array"
|
97
|
+
elif vellum_type == "FUNCTION_CALL":
|
98
|
+
return "object"
|
99
|
+
elif vellum_type == "IMAGE":
|
100
|
+
return "object"
|
101
|
+
elif vellum_type == "AUDIO":
|
102
|
+
return "object"
|
103
|
+
elif vellum_type == "DOCUMENT":
|
104
|
+
return "object"
|
105
|
+
elif vellum_type == "NULL":
|
106
|
+
return "null"
|
107
|
+
else:
|
108
|
+
return "object"
|
109
|
+
|
110
|
+
|
81
111
|
def _is_type_optionally_equal(type_: Type, target_type: Type) -> bool:
|
82
112
|
if type_ == target_type:
|
83
113
|
return True
|
@@ -42,6 +42,7 @@ from vellum.workflows.events.node import (
|
|
42
42
|
NodeExecutionStreamingBody,
|
43
43
|
NodeExecutionStreamingEvent,
|
44
44
|
)
|
45
|
+
from vellum.workflows.events.stream import WorkflowEventGenerator
|
45
46
|
from vellum.workflows.events.workflow import (
|
46
47
|
GenericWorkflowEvent,
|
47
48
|
WorkflowExecutionFulfilledBody,
|
@@ -167,7 +168,7 @@ class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
|
|
167
168
|
WorkflowExecutionPausedEvent,
|
168
169
|
]
|
169
170
|
|
170
|
-
WorkflowEventStream =
|
171
|
+
WorkflowEventStream = WorkflowEventGenerator[WorkflowEvent]
|
171
172
|
|
172
173
|
def __init__(
|
173
174
|
self,
|
@@ -444,7 +445,7 @@ class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
|
|
444
445
|
"""
|
445
446
|
|
446
447
|
should_yield = event_filter or workflow_event_filter
|
447
|
-
|
448
|
+
runner_stream = WorkflowRunner(
|
448
449
|
self,
|
449
450
|
inputs=inputs,
|
450
451
|
state=state,
|
@@ -454,9 +455,14 @@ class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
|
|
454
455
|
node_output_mocks=node_output_mocks,
|
455
456
|
max_concurrency=max_concurrency,
|
456
457
|
init_execution_context=self._execution_context,
|
457
|
-
).stream()
|
458
|
-
|
459
|
-
|
458
|
+
).stream()
|
459
|
+
|
460
|
+
def _generate_filtered_events() -> Generator[BaseWorkflow.WorkflowEvent, None, None]:
|
461
|
+
for event in runner_stream:
|
462
|
+
if should_yield(self.__class__, event):
|
463
|
+
yield event
|
464
|
+
|
465
|
+
return WorkflowEventGenerator(_generate_filtered_events(), runner_stream.span_id)
|
460
466
|
|
461
467
|
def validate(self) -> None:
|
462
468
|
"""
|
@@ -3,22 +3,22 @@ vellum_cli/README.md,sha256=2NudRoLzWxNKqnuVy1JuQ7DerIaxWGYkrH8kMd-asIE,90
|
|
3
3
|
vellum_cli/__init__.py,sha256=oi-vvNVepu23IBBjhA5uUIDVYBPqQ3EzxWZAPn2S64c,12700
|
4
4
|
vellum_cli/aliased_group.py,sha256=ugW498j0yv4ALJ8vS9MsO7ctDW7Jlir9j6nE_uHAP8c,3363
|
5
5
|
vellum_cli/config.py,sha256=v5BmZ-t_v4Jmqd7KVuQMZF2pRI-rbMspSkVYXIRoTmI,9448
|
6
|
-
vellum_cli/image_push.py,sha256=
|
6
|
+
vellum_cli/image_push.py,sha256=rPeSfTlFpdTzwTdnXRL82OVd61qMoGFGLxnLjZLU98Q,10596
|
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=TqzaJrI_ty_1GuB3HX3EKfAnbMUF14FWfMMTD06vn2I,10428
|
12
12
|
vellum_cli/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
13
|
vellum_cli/tests/conftest.py,sha256=AFYZryKA2qnUuCPBxBKmHLFoPiE0WhBFFej9tNwSHdc,1526
|
14
14
|
vellum_cli/tests/test_config.py,sha256=uvKGDc8BoVyT9_H0Z-g8469zVxomn6Oi3Zj-vK7O_wU,2631
|
15
|
-
vellum_cli/tests/test_image_push.py,sha256=
|
15
|
+
vellum_cli/tests/test_image_push.py,sha256=xXZjI-CDp166cmk5P1NTa-aogergeIbcdfK4_KBsoHc,9095
|
16
16
|
vellum_cli/tests/test_image_push_error_handling.py,sha256=_Wjfkn1orI2K4Ahzqz4u8T13or7NOX01K4BtcTuTIOM,7107
|
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=3ucVRThEmTadlV9LrJdCCrr1Ofj3rOjG6ue0BNR2UC0,2523
|
20
20
|
vellum_cli/tests/test_pull.py,sha256=hxMbW_j0weDDrkzVGpvLpFcwNQdn-fxTv4wBHeYizzc,49904
|
21
|
-
vellum_cli/tests/test_push.py,sha256=
|
21
|
+
vellum_cli/tests/test_push.py,sha256=uyWknZ1CBkxxfKVdwcyv7fkGSxvvSNRdJegp5cV-_V4,35167
|
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
|
@@ -32,7 +32,7 @@ vellum_ee/workflows/display/nodes/get_node_display_class.py,sha256=jI_kUi9LnNLDp
|
|
32
32
|
vellum_ee/workflows/display/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
33
33
|
vellum_ee/workflows/display/nodes/tests/test_base_node_display.py,sha256=Z4Mf7xLCNiblSbpKI0BrV5modQr-ZcFzhfir_OSyTTs,2997
|
34
34
|
vellum_ee/workflows/display/nodes/types.py,sha256=St1BB6no528OyELGiyRabWao0GGw6mLhstQAvEACbGk,247
|
35
|
-
vellum_ee/workflows/display/nodes/utils.py,sha256=
|
35
|
+
vellum_ee/workflows/display/nodes/utils.py,sha256=sloya5TpXsnot1HURc9L51INwflRqUzHxRVnCS9Cd-4,973
|
36
36
|
vellum_ee/workflows/display/nodes/vellum/__init__.py,sha256=nUIgH2s0-7IbQRNrBhLPyRNe8YIrx3Yo9HeeW-aXXFk,1668
|
37
37
|
vellum_ee/workflows/display/nodes/vellum/api_node.py,sha256=5Uq8x08F64yrBcqbfsVeuoGnTa9eoOPumYzZZrDPmr0,8847
|
38
38
|
vellum_ee/workflows/display/nodes/vellum/base_adornment_node.py,sha256=rJbHZBg9A_v2bjk-R6MfWzShcrS2gcKIOyYGoqwTx8s,6353
|
@@ -142,7 +142,7 @@ vellum/client/README.md,sha256=CuGUYnaE0Imt0KqQ4sIPaUghCjLHkF3DdEvZWu14-8s,4807
|
|
142
142
|
vellum/client/__init__.py,sha256=AYopGv2ZRVn3zsU8_km6KOvEHDbXiTPCVuYVI7bWvdA,120166
|
143
143
|
vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
|
144
144
|
vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
|
145
|
-
vellum/client/core/client_wrapper.py,sha256=
|
145
|
+
vellum/client/core/client_wrapper.py,sha256=TaQmB_GjRpi-KMiR3qBKQTy1uf4a2n9roQbenkHDwBQ,1869
|
146
146
|
vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
|
147
147
|
vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
|
148
148
|
vellum/client/core/http_client.py,sha256=Z77OIxIbL4OAB2IDqjRq_sYa5yNYAWfmdhdCSSvh6Y4,19552
|
@@ -830,7 +830,7 @@ vellum/evaluations/utils/paginator.py,sha256=rEED_BJAXAM6tM1yMwHePNzszjq_tTq4NbQ
|
|
830
830
|
vellum/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
831
831
|
vellum/plugins/pydantic.py,sha256=j4ApZ5WyaoCX6v54qNoShhMFyft_uKWTkyAFz5wbcgg,3619
|
832
832
|
vellum/plugins/utils.py,sha256=cPmxE9R2CK1bki2jKE8rB-G9zMf2pzHjSPDHFPXwd3Q,878
|
833
|
-
vellum/plugins/vellum_mypy.py,sha256=
|
833
|
+
vellum/plugins/vellum_mypy.py,sha256=hfjC2rIxNdQuJa6fIN4PDgODnQ3YaUszyaV2eNbLJlE,27952
|
834
834
|
vellum/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
835
835
|
vellum/prompts/blocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
836
836
|
vellum/prompts/blocks/compilation.py,sha256=qeC_4La5auQkm4EyzCMpN34F5R8mjiGcLV7IxKgVf3k,9973
|
@@ -1509,12 +1509,13 @@ vellum/workflows/environment/__init__.py,sha256=TJz0m9dwIs6YOwCTeuN0HHsU-ecyjc1O
|
|
1509
1509
|
vellum/workflows/environment/environment.py,sha256=Ck3RPKXJvtMGx_toqYQQQF-ZwXm5ijVwJpEPTeIJ4_Q,471
|
1510
1510
|
vellum/workflows/errors/__init__.py,sha256=tWGPu5xyAU8gRb8_bl0fL7OfU3wxQ9UH6qVwy4X4P_Q,113
|
1511
1511
|
vellum/workflows/errors/types.py,sha256=nUWuniEfrhdtb-_2GzoDGlYnSJ_yuNUGjVkaKLNr-rM,4049
|
1512
|
-
vellum/workflows/events/__init__.py,sha256=
|
1512
|
+
vellum/workflows/events/__init__.py,sha256=V4mh766fyA70WvHelm9kfVZGrUgEKcJ9tJt8EepfQYU,832
|
1513
1513
|
vellum/workflows/events/node.py,sha256=TaawUxKaZG8cv_GkiKnJmjOmC4Ic0wMlsxUduF2Rbpw,5446
|
1514
|
+
vellum/workflows/events/stream.py,sha256=xhXJTZirFi0xad5neAQNogrIQ4h47fpnKbVC3vCM5Js,889
|
1514
1515
|
vellum/workflows/events/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1515
1516
|
vellum/workflows/events/tests/test_event.py,sha256=elg5j3MOdWQe-JjshopqVwd716Jrvtr9P_V2JUGZC60,17866
|
1516
1517
|
vellum/workflows/events/types.py,sha256=LwgFlMRbptJvdPtPO1POUtGtbhGw7BSuvgHxNSgS7N8,4652
|
1517
|
-
vellum/workflows/events/workflow.py,sha256=
|
1518
|
+
vellum/workflows/events/workflow.py,sha256=7rb1evKsTCRUdCnisAM5Anc19ZKGxnsmzwOOv6jwWEI,7761
|
1518
1519
|
vellum/workflows/exceptions.py,sha256=NiBiR3ggfmPxBVqD-H1SqmjI-7mIn0EStSN1BqApvCM,1213
|
1519
1520
|
vellum/workflows/expressions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1520
1521
|
vellum/workflows/expressions/accessor.py,sha256=1kY0sYfednQ_u0kh1Df2WTsDREVIOzU7UuZc5jvj5xw,2861
|
@@ -1658,9 +1659,9 @@ vellum/workflows/nodes/experimental/__init__.py,sha256=_tpZGWAZLydcKxfrj1-plrZeT
|
|
1658
1659
|
vellum/workflows/nodes/experimental/openai_chat_completion_node/__init__.py,sha256=lsyD9laR9p7kx5-BXGH2gUTM242UhKy8SMV0SR6S2iE,90
|
1659
1660
|
vellum/workflows/nodes/experimental/openai_chat_completion_node/node.py,sha256=cKI2Ls25L-JVt4z4a2ozQa-YBeVy21Z7BQ32Sj7iBPE,10460
|
1660
1661
|
vellum/workflows/nodes/experimental/tool_calling_node/__init__.py,sha256=S7OzT3I4cyOU5Beoz87nPwCejCMP2FsHBFL8OcVmxJ4,118
|
1661
|
-
vellum/workflows/nodes/experimental/tool_calling_node/node.py,sha256=
|
1662
|
+
vellum/workflows/nodes/experimental/tool_calling_node/node.py,sha256=1Sp-Jnziz8lK5t7snBIwhMk_wKzsXu_aqW7xAeHKc_w,5797
|
1662
1663
|
vellum/workflows/nodes/experimental/tool_calling_node/tests/test_node.py,sha256=7x_o81vT7gWtVw3zDppcWnlJbakgxx_oI1esqhs2gpI,4551
|
1663
|
-
vellum/workflows/nodes/experimental/tool_calling_node/utils.py,sha256=
|
1664
|
+
vellum/workflows/nodes/experimental/tool_calling_node/utils.py,sha256=UiQ1o2tDl7EYLHY9HRWLa-MeuYPYfXp8lo2qNFakh2Q,9955
|
1664
1665
|
vellum/workflows/nodes/mocks.py,sha256=a1FjWEIocseMfjzM-i8DNozpUsaW0IONRpZmXBoWlyc,10455
|
1665
1666
|
vellum/workflows/nodes/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1666
1667
|
vellum/workflows/nodes/tests/test_mocks.py,sha256=mfPvrs75PKcsNsbJLQAN6PDFoVqs9TmQxpdyFKDdO60,7837
|
@@ -1688,7 +1689,7 @@ vellum/workflows/references/workflow_input.py,sha256=W3rOK1EPd2gYHb04WJwmNm1CUSd
|
|
1688
1689
|
vellum/workflows/resolvers/__init__.py,sha256=eH6hTvZO4IciDaf_cf7aM2vs-DkBDyJPycOQevJxQnI,82
|
1689
1690
|
vellum/workflows/resolvers/base.py,sha256=WHra9LRtlTuB1jmuNqkfVE2JUgB61Cyntn8f0b0WZg4,411
|
1690
1691
|
vellum/workflows/runner/__init__.py,sha256=i1iG5sAhtpdsrlvwgH6B-m49JsINkiWyPWs8vyT-bqM,72
|
1691
|
-
vellum/workflows/runner/runner.py,sha256=
|
1692
|
+
vellum/workflows/runner/runner.py,sha256=itKhjnJBIXrKcI3nKbKsAwcmeP4pn5BowX-LaTPu_VU,33911
|
1692
1693
|
vellum/workflows/sandbox.py,sha256=GVJzVjMuYzOBnSrboB0_6MMRZWBluAyQ2o7syeaeBd0,2235
|
1693
1694
|
vellum/workflows/state/__init__.py,sha256=yUUdR-_Vl7UiixNDYQZ-GEM_kJI9dnOia75TtuNEsnE,60
|
1694
1695
|
vellum/workflows/state/base.py,sha256=WIMJYyuHUrP4zt0Nudk66HAK1L6GgGmsU_GQp7BGE2U,22189
|
@@ -1710,24 +1711,24 @@ vellum/workflows/types/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
|
|
1710
1711
|
vellum/workflows/types/tests/test_utils.py,sha256=UnZog59tR577mVwqZRqqWn2fScoOU1H6up0EzS8zYhw,2536
|
1711
1712
|
vellum/workflows/types/utils.py,sha256=axxHbPLsnjhEOnMZrc5YarFd-P2bnsacBDQGNCvY8OY,6367
|
1712
1713
|
vellum/workflows/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1713
|
-
vellum/workflows/utils/functions.py,sha256=
|
1714
|
+
vellum/workflows/utils/functions.py,sha256=Gw9akY-_xU_kJpbkYvQ-07hOOLJpqq0rtch_3FbgFQ0,7169
|
1714
1715
|
vellum/workflows/utils/names.py,sha256=QLUqfJ1tmSEeUwBKTTiv_Qk3QGbInC2RSmlXfGXc8Wo,380
|
1715
1716
|
vellum/workflows/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1716
|
-
vellum/workflows/utils/tests/test_functions.py,sha256=
|
1717
|
+
vellum/workflows/utils/tests/test_functions.py,sha256=4mhIhZdlZdiboq1NUhJlOvDeRrpG-Oa_HrstvSbjg64,18368
|
1717
1718
|
vellum/workflows/utils/tests/test_names.py,sha256=aOqpyvMsOEK_9mg_-yaNxQDW7QQfwqsYs37PseyLhxw,402
|
1718
1719
|
vellum/workflows/utils/tests/test_uuids.py,sha256=i77ABQ0M3S-aFLzDXHJq_yr5FPkJEWCMBn1HJ3DObrE,437
|
1719
|
-
vellum/workflows/utils/tests/test_vellum_variables.py,sha256=
|
1720
|
+
vellum/workflows/utils/tests/test_vellum_variables.py,sha256=vbnKgm41aB5OXlO-ZIPbhQ6xDiZkT8KMxCLqz4zocWY,1791
|
1720
1721
|
vellum/workflows/utils/uuids.py,sha256=DFzPv9RCvsKhvdTEIQyfSek2A31D6S_QcmeLPbgrgTY,739
|
1721
|
-
vellum/workflows/utils/vellum_variables.py,sha256=
|
1722
|
+
vellum/workflows/utils/vellum_variables.py,sha256=tDWGyE8CfxYaCQQfMwTHqQNgK5V5sJMuhjLsliT8Ar4,4286
|
1722
1723
|
vellum/workflows/vellum_client.py,sha256=xkfoucodxNK5JR2-lbRqZx3xzDgExWkP6kySrpi_Ubc,1079
|
1723
1724
|
vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
|
1724
|
-
vellum/workflows/workflows/base.py,sha256=
|
1725
|
+
vellum/workflows/workflows/base.py,sha256=ehJSHDf1vuNjJtKryqKgb5HKGtx_D-wWUiJNBWZ50JU,24347
|
1725
1726
|
vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
|
1726
1727
|
vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
1727
1728
|
vellum/workflows/workflows/tests/test_base_workflow.py,sha256=fROqff6AZpCIzaSwOKSdtYy4XR0UZQ6ejxL3RJOSJVs,20447
|
1728
1729
|
vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
|
1729
|
-
vellum_ai-0.14.
|
1730
|
-
vellum_ai-0.14.
|
1731
|
-
vellum_ai-0.14.
|
1732
|
-
vellum_ai-0.14.
|
1733
|
-
vellum_ai-0.14.
|
1730
|
+
vellum_ai-0.14.72.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
|
1731
|
+
vellum_ai-0.14.72.dist-info/METADATA,sha256=5rmPI1o0CHUiw7gPjZq2ZSjkiaWzLTbWTxG0pCyP3WA,5556
|
1732
|
+
vellum_ai-0.14.72.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
1733
|
+
vellum_ai-0.14.72.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
|
1734
|
+
vellum_ai-0.14.72.dist-info/RECORD,,
|
vellum_cli/image_push.py
CHANGED
@@ -30,12 +30,8 @@ def image_push_command(
|
|
30
30
|
if not os.path.exists(source):
|
31
31
|
handle_cli_error(logger, "Dockerfile not found", f"Dockerfile does not exist: {source}")
|
32
32
|
|
33
|
-
source_dir = os.path.dirname(source)
|
34
|
-
dockerfile_name = os.path.basename(source)
|
35
|
-
|
36
33
|
build_result = subprocess.run(
|
37
|
-
["docker", "buildx", "build", "-f",
|
38
|
-
cwd=source_dir,
|
34
|
+
["docker", "buildx", "build", "-f", source, "--platform=linux/amd64", "-t", image, "."],
|
39
35
|
stdout=subprocess.PIPE,
|
40
36
|
stderr=subprocess.PIPE,
|
41
37
|
)
|
vellum_cli/push.py
CHANGED
@@ -242,6 +242,13 @@ def push_command(
|
|
242
242
|
{json.dumps(response.proposed_diffs, indent=2)}
|
243
243
|
"""
|
244
244
|
) # type: ignore[attr-defined]
|
245
|
+
|
246
|
+
error_list = list(workflow_display.errors)
|
247
|
+
has_errors = len(error_list) > 0
|
248
|
+
has_diffs = response.proposed_diffs is not None and response.proposed_diffs
|
249
|
+
|
250
|
+
if has_errors or has_diffs:
|
251
|
+
exit(1)
|
245
252
|
else:
|
246
253
|
default_api_url = client._client_wrapper._environment.default
|
247
254
|
base_url = default_api_url.split("/v1")[0].replace("//api.", "//app.")
|
@@ -209,13 +209,12 @@ def test_image_push_with_source_success(
|
|
209
209
|
"buildx",
|
210
210
|
"build",
|
211
211
|
"-f",
|
212
|
-
|
212
|
+
dockerfile_path,
|
213
213
|
"--platform=linux/amd64",
|
214
214
|
"-t",
|
215
215
|
"myimage:latest",
|
216
216
|
".",
|
217
217
|
]
|
218
|
-
assert build_call[1]["cwd"] == mock_temp_dir
|
219
218
|
|
220
219
|
assert "Docker build completed successfully" in result.output
|
221
220
|
assert "Image successfully pushed" in result.output
|
vellum_cli/tests/test_push.py
CHANGED
@@ -444,8 +444,8 @@ class ExampleWorkflow(BaseWorkflow):
|
|
444
444
|
runner = CliRunner(mix_stderr=True)
|
445
445
|
result = runner.invoke(cli_main, ["push", module, "--dry-run"])
|
446
446
|
|
447
|
-
# THEN it should
|
448
|
-
assert result.exit_code ==
|
447
|
+
# THEN it should fail with exit code 1 due to errors
|
448
|
+
assert result.exit_code == 1
|
449
449
|
|
450
450
|
# AND we should have called the push API with the dry-run option
|
451
451
|
vellum_client.workflows.push.assert_called_once()
|
@@ -459,6 +459,37 @@ class ExampleWorkflow(BaseWorkflow):
|
|
459
459
|
assert "iterable_item_added" in result.output
|
460
460
|
|
461
461
|
|
462
|
+
def test_push__dry_run_option_no_errors_returns_success(mock_module, vellum_client):
|
463
|
+
"""Test that dry-run returns exit code 0 when there are no errors or diffs"""
|
464
|
+
# GIVEN a workflow module with a valid workflow (using the same pattern as happy path test)
|
465
|
+
temp_dir = mock_module.temp_dir
|
466
|
+
module = mock_module.module
|
467
|
+
_ensure_workflow_py(temp_dir, module)
|
468
|
+
|
469
|
+
# AND the push API call returns successfully with no errors and no diffs
|
470
|
+
vellum_client.workflows.push.return_value = WorkflowPushResponse(
|
471
|
+
workflow_sandbox_id=str(uuid4()),
|
472
|
+
proposed_diffs=None,
|
473
|
+
)
|
474
|
+
|
475
|
+
# WHEN calling `vellum push` with dry-run
|
476
|
+
runner = CliRunner(mix_stderr=True)
|
477
|
+
result = runner.invoke(cli_main, ["push", module, "--dry-run"])
|
478
|
+
|
479
|
+
# THEN it should succeed with exit code 0
|
480
|
+
assert result.exit_code == 0
|
481
|
+
|
482
|
+
# AND we should have called the push API with the dry-run option
|
483
|
+
vellum_client.workflows.push.assert_called_once()
|
484
|
+
call_args = vellum_client.workflows.push.call_args.kwargs
|
485
|
+
assert call_args["dry_run"] is True
|
486
|
+
|
487
|
+
# AND the report should be in the output
|
488
|
+
assert "## Errors" in result.output
|
489
|
+
assert "No errors found." in result.output
|
490
|
+
assert "## Proposed Diffs" in result.output
|
491
|
+
|
492
|
+
|
462
493
|
def test_push__strict_option_returns_diffs(mock_module, vellum_client):
|
463
494
|
# GIVEN a single workflow configured
|
464
495
|
temp_dir = mock_module.temp_dir
|
@@ -8,11 +8,11 @@ _T = TypeVar("_T")
|
|
8
8
|
|
9
9
|
|
10
10
|
@overload
|
11
|
-
def raise_if_descriptor(
|
11
|
+
def raise_if_descriptor(node_attr: BaseDescriptor[_T]) -> _T: ...
|
12
12
|
|
13
13
|
|
14
14
|
@overload
|
15
|
-
def raise_if_descriptor(
|
15
|
+
def raise_if_descriptor(node_attr: _T) -> _T: ...
|
16
16
|
|
17
17
|
|
18
18
|
def raise_if_descriptor(node_attr: Union[NodeReference[_T], _T]) -> Optional[_T]:
|
File without changes
|
File without changes
|
File without changes
|