vellum-ai 1.2.4__py3-none-any.whl → 1.2.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vellum/__init__.py +48 -0
- vellum/client/core/client_wrapper.py +2 -2
- vellum/client/resources/workflows/client.py +20 -0
- vellum/client/resources/workflows/raw_client.py +20 -0
- vellum/client/types/__init__.py +48 -0
- vellum/client/types/audio_input.py +30 -0
- vellum/client/types/code_executor_input.py +8 -0
- vellum/client/types/document_input.py +30 -0
- vellum/client/types/image_input.py +30 -0
- vellum/client/types/named_scenario_input_audio_variable_value_request.py +22 -0
- vellum/client/types/named_scenario_input_document_variable_value_request.py +22 -0
- vellum/client/types/named_scenario_input_image_variable_value_request.py +22 -0
- vellum/client/types/named_scenario_input_request.py +8 -0
- vellum/client/types/named_scenario_input_video_variable_value_request.py +22 -0
- vellum/client/types/named_test_case_audio_variable_value.py +26 -0
- vellum/client/types/named_test_case_audio_variable_value_request.py +26 -0
- vellum/client/types/named_test_case_document_variable_value.py +22 -0
- vellum/client/types/named_test_case_document_variable_value_request.py +22 -0
- vellum/client/types/named_test_case_image_variable_value.py +22 -0
- vellum/client/types/named_test_case_image_variable_value_request.py +22 -0
- vellum/client/types/named_test_case_variable_value.py +8 -0
- vellum/client/types/named_test_case_variable_value_request.py +8 -0
- vellum/client/types/named_test_case_video_variable_value.py +22 -0
- vellum/client/types/named_test_case_video_variable_value_request.py +22 -0
- vellum/client/types/node_execution_span_attributes.py +1 -0
- vellum/client/types/scenario_input.py +11 -1
- vellum/client/types/scenario_input_audio_variable_value.py +22 -0
- vellum/client/types/scenario_input_document_variable_value.py +22 -0
- vellum/client/types/scenario_input_image_variable_value.py +22 -0
- vellum/client/types/scenario_input_video_variable_value.py +22 -0
- vellum/client/types/span_link.py +1 -1
- vellum/client/types/span_link_type_enum.py +1 -1
- vellum/client/types/test_case_audio_variable_value.py +27 -0
- vellum/client/types/test_case_document_variable_value.py +27 -0
- vellum/client/types/test_case_image_variable_value.py +27 -0
- vellum/client/types/test_case_variable_value.py +8 -0
- vellum/client/types/test_case_video_variable_value.py +27 -0
- vellum/client/types/video_input.py +30 -0
- vellum/client/types/workflow_push_deployment_config_request.py +1 -0
- vellum/types/audio_input.py +3 -0
- vellum/types/document_input.py +3 -0
- vellum/types/image_input.py +3 -0
- vellum/types/named_scenario_input_audio_variable_value_request.py +3 -0
- vellum/types/named_scenario_input_document_variable_value_request.py +3 -0
- vellum/types/named_scenario_input_image_variable_value_request.py +3 -0
- vellum/types/named_scenario_input_video_variable_value_request.py +3 -0
- vellum/types/named_test_case_audio_variable_value.py +3 -0
- vellum/types/named_test_case_audio_variable_value_request.py +3 -0
- vellum/types/named_test_case_document_variable_value.py +3 -0
- vellum/types/named_test_case_document_variable_value_request.py +3 -0
- vellum/types/named_test_case_image_variable_value.py +3 -0
- vellum/types/named_test_case_image_variable_value_request.py +3 -0
- vellum/types/named_test_case_video_variable_value.py +3 -0
- vellum/types/named_test_case_video_variable_value_request.py +3 -0
- vellum/types/scenario_input_audio_variable_value.py +3 -0
- vellum/types/scenario_input_document_variable_value.py +3 -0
- vellum/types/scenario_input_image_variable_value.py +3 -0
- vellum/types/scenario_input_video_variable_value.py +3 -0
- vellum/types/test_case_audio_variable_value.py +3 -0
- vellum/types/test_case_document_variable_value.py +3 -0
- vellum/types/test_case_image_variable_value.py +3 -0
- vellum/types/test_case_video_variable_value.py +3 -0
- vellum/types/video_input.py +3 -0
- vellum/workflows/resolvers/base.py +18 -1
- vellum/workflows/resolvers/resolver.py +42 -0
- vellum/workflows/resolvers/tests/test_resolver.py +59 -0
- vellum/workflows/workflows/base.py +3 -0
- {vellum_ai-1.2.4.dist-info → vellum_ai-1.2.5.dist-info}/METADATA +1 -1
- {vellum_ai-1.2.4.dist-info → vellum_ai-1.2.5.dist-info}/RECORD +74 -24
- vellum_ee/workflows/display/utils/events.py +19 -1
- vellum_ee/workflows/display/utils/tests/test_events.py +42 -0
- {vellum_ai-1.2.4.dist-info → vellum_ai-1.2.5.dist-info}/LICENSE +0 -0
- {vellum_ai-1.2.4.dist-info → vellum_ai-1.2.5.dist-info}/WHEEL +0 -0
- {vellum_ai-1.2.4.dist-info → vellum_ai-1.2.5.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
2
|
+
|
3
|
+
import typing
|
4
|
+
|
5
|
+
import pydantic
|
6
|
+
from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
|
7
|
+
from .vellum_video import VellumVideo
|
8
|
+
|
9
|
+
|
10
|
+
class VideoInput(UniversalBaseModel):
|
11
|
+
"""
|
12
|
+
A user input representing a Vellum Video value
|
13
|
+
"""
|
14
|
+
|
15
|
+
name: str = pydantic.Field()
|
16
|
+
"""
|
17
|
+
The variable's name
|
18
|
+
"""
|
19
|
+
|
20
|
+
type: typing.Literal["VIDEO"] = "VIDEO"
|
21
|
+
value: VellumVideo
|
22
|
+
|
23
|
+
if IS_PYDANTIC_V2:
|
24
|
+
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
25
|
+
else:
|
26
|
+
|
27
|
+
class Config:
|
28
|
+
frozen = True
|
29
|
+
smart_union = True
|
30
|
+
extra = pydantic.Extra.allow
|
@@ -11,6 +11,7 @@ class WorkflowPushDeploymentConfigRequest(UniversalBaseModel):
|
|
11
11
|
name: typing.Optional[str] = None
|
12
12
|
description: typing.Optional[str] = None
|
13
13
|
release_tags: typing.Optional[typing.List[str]] = None
|
14
|
+
release_description: typing.Optional[str] = None
|
14
15
|
|
15
16
|
if IS_PYDANTIC_V2:
|
16
17
|
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
@@ -1,11 +1,24 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
from
|
2
|
+
from uuid import UUID
|
3
|
+
from typing import TYPE_CHECKING, Iterator, Optional, Type
|
3
4
|
|
4
5
|
from vellum.workflows.events.workflow import WorkflowEvent
|
5
6
|
from vellum.workflows.state.base import BaseState
|
6
7
|
|
8
|
+
if TYPE_CHECKING:
|
9
|
+
from vellum.workflows.state.context import WorkflowContext
|
10
|
+
from vellum.workflows.workflows.base import BaseWorkflow
|
11
|
+
|
7
12
|
|
8
13
|
class BaseWorkflowResolver(ABC):
|
14
|
+
def __init__(self):
|
15
|
+
self._context: Optional["WorkflowContext"] = None
|
16
|
+
self._workflow_class: Optional[Type["BaseWorkflow"]] = None
|
17
|
+
|
18
|
+
def register_workflow_instance(self, workflow_instance: "BaseWorkflow") -> None:
|
19
|
+
self._workflow_class = type(workflow_instance)
|
20
|
+
self._context = workflow_instance.context
|
21
|
+
|
9
22
|
@abstractmethod
|
10
23
|
def get_latest_execution_events(self) -> Iterator[WorkflowEvent]:
|
11
24
|
pass
|
@@ -13,3 +26,7 @@ class BaseWorkflowResolver(ABC):
|
|
13
26
|
@abstractmethod
|
14
27
|
def get_state_snapshot_history(self) -> Iterator[BaseState]:
|
15
28
|
pass
|
29
|
+
|
30
|
+
@abstractmethod
|
31
|
+
def load_state(self, previous_execution_id: Optional[UUID] = None) -> Optional[BaseState]:
|
32
|
+
pass
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import logging
|
2
|
+
from uuid import UUID
|
3
|
+
from typing import Iterator, Optional
|
4
|
+
|
5
|
+
from vellum.workflows.events.workflow import WorkflowEvent
|
6
|
+
from vellum.workflows.resolvers.base import BaseWorkflowResolver
|
7
|
+
from vellum.workflows.state.base import BaseState, StateMeta
|
8
|
+
|
9
|
+
logger = logging.getLogger(__name__)
|
10
|
+
|
11
|
+
|
12
|
+
class VellumResolver(BaseWorkflowResolver):
|
13
|
+
def get_latest_execution_events(self) -> Iterator[WorkflowEvent]:
|
14
|
+
return iter([])
|
15
|
+
|
16
|
+
def get_state_snapshot_history(self) -> Iterator[BaseState]:
|
17
|
+
return iter([])
|
18
|
+
|
19
|
+
def load_state(self, previous_execution_id: Optional[UUID] = None) -> Optional[BaseState]:
|
20
|
+
if previous_execution_id is None:
|
21
|
+
return None
|
22
|
+
|
23
|
+
if not self._context:
|
24
|
+
logger.warning("Cannot load state: No workflow context registered")
|
25
|
+
return None
|
26
|
+
|
27
|
+
client = self._context.vellum_client
|
28
|
+
response = client.workflow_executions.retrieve_workflow_execution_detail(
|
29
|
+
execution_id=str(previous_execution_id),
|
30
|
+
)
|
31
|
+
|
32
|
+
if response.state is None:
|
33
|
+
return None
|
34
|
+
|
35
|
+
meta = StateMeta.model_validate(response.state.pop("meta"))
|
36
|
+
|
37
|
+
if self._workflow_class:
|
38
|
+
state_class = self._workflow_class.get_state_class()
|
39
|
+
return state_class(**response.state, meta=meta)
|
40
|
+
else:
|
41
|
+
logger.warning("No workflow class registered, falling back to BaseState")
|
42
|
+
return BaseState(**response.state, meta=meta)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
from unittest.mock import Mock
|
3
|
+
from uuid import uuid4
|
4
|
+
|
5
|
+
from vellum.client.types.workflow_execution_detail import WorkflowExecutionDetail
|
6
|
+
from vellum.workflows import BaseWorkflow
|
7
|
+
from vellum.workflows.inputs.base import BaseInputs
|
8
|
+
from vellum.workflows.resolvers.resolver import VellumResolver
|
9
|
+
from vellum.workflows.state.base import BaseState, NodeExecutionCache
|
10
|
+
from vellum.workflows.state.context import WorkflowContext
|
11
|
+
|
12
|
+
|
13
|
+
def test_load_state_with_context_success():
|
14
|
+
"""Test load_state successfully loads state when context and client are available."""
|
15
|
+
resolver = VellumResolver()
|
16
|
+
execution_id = uuid4()
|
17
|
+
|
18
|
+
class TestState(BaseState):
|
19
|
+
test_key: str = "test_value"
|
20
|
+
|
21
|
+
class TestWorkflow(BaseWorkflow[BaseInputs, TestState]):
|
22
|
+
pass
|
23
|
+
|
24
|
+
# GIVEN a state dictionary that matches what the resolver expects
|
25
|
+
state_dict = {
|
26
|
+
"test_key": "test_value",
|
27
|
+
"meta": {
|
28
|
+
"workflow_definition": "MockWorkflow",
|
29
|
+
"id": str(uuid4()),
|
30
|
+
"span_id": str(uuid4()),
|
31
|
+
"updated_ts": datetime.now().isoformat(),
|
32
|
+
"workflow_inputs": BaseInputs(),
|
33
|
+
"external_inputs": {},
|
34
|
+
"node_outputs": {},
|
35
|
+
"node_execution_cache": NodeExecutionCache(),
|
36
|
+
"parent": None,
|
37
|
+
},
|
38
|
+
}
|
39
|
+
|
40
|
+
mock_response = WorkflowExecutionDetail(
|
41
|
+
span_id="test-span-id", start=datetime.now(), inputs=[], outputs=[], spans=[], state=state_dict
|
42
|
+
)
|
43
|
+
|
44
|
+
mock_client = Mock()
|
45
|
+
mock_client.workflow_executions.retrieve_workflow_execution_detail.return_value = mock_response
|
46
|
+
|
47
|
+
# AND context with the test workflow class
|
48
|
+
context = WorkflowContext(vellum_client=mock_client)
|
49
|
+
TestWorkflow(context=context, resolvers=[resolver])
|
50
|
+
|
51
|
+
result = resolver.load_state(previous_execution_id=execution_id)
|
52
|
+
|
53
|
+
# THEN should return an instance of TestWorkflow.State, not BaseState
|
54
|
+
assert isinstance(result, TestState)
|
55
|
+
assert result.test_key == "test_value"
|
56
|
+
|
57
|
+
mock_client.workflow_executions.retrieve_workflow_execution_detail.assert_called_once_with(
|
58
|
+
execution_id=str(execution_id)
|
59
|
+
)
|
@@ -251,6 +251,9 @@ class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
|
|
251
251
|
for emitter in self.emitters:
|
252
252
|
emitter.register_context(self._context)
|
253
253
|
|
254
|
+
for resolver in self.resolvers:
|
255
|
+
resolver.register_workflow_instance(self)
|
256
|
+
|
254
257
|
self.validate()
|
255
258
|
|
256
259
|
@property
|