vellum-ai 0.9.16rc2__py3-none-any.whl → 0.9.16rc4__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/plugins/__init__.py +0 -0
- vellum/plugins/pydantic.py +74 -0
- vellum/plugins/utils.py +19 -0
- vellum/plugins/vellum_mypy.py +639 -3
- vellum/workflows/README.md +90 -0
- vellum/workflows/__init__.py +5 -0
- vellum/workflows/constants.py +43 -0
- vellum/workflows/descriptors/__init__.py +0 -0
- vellum/workflows/descriptors/base.py +339 -0
- vellum/workflows/descriptors/tests/test_utils.py +83 -0
- vellum/workflows/descriptors/utils.py +90 -0
- vellum/workflows/edges/__init__.py +5 -0
- vellum/workflows/edges/edge.py +23 -0
- vellum/workflows/emitters/__init__.py +5 -0
- vellum/workflows/emitters/base.py +14 -0
- vellum/workflows/environment/__init__.py +5 -0
- vellum/workflows/environment/environment.py +7 -0
- vellum/workflows/errors/__init__.py +6 -0
- vellum/workflows/errors/types.py +20 -0
- vellum/workflows/events/__init__.py +31 -0
- vellum/workflows/events/node.py +125 -0
- vellum/workflows/events/tests/__init__.py +0 -0
- vellum/workflows/events/tests/test_event.py +216 -0
- vellum/workflows/events/types.py +52 -0
- vellum/workflows/events/utils.py +5 -0
- vellum/workflows/events/workflow.py +139 -0
- vellum/workflows/exceptions.py +15 -0
- vellum/workflows/expressions/__init__.py +0 -0
- vellum/workflows/expressions/accessor.py +52 -0
- vellum/workflows/expressions/and_.py +32 -0
- vellum/workflows/expressions/begins_with.py +31 -0
- vellum/workflows/expressions/between.py +38 -0
- vellum/workflows/expressions/coalesce_expression.py +41 -0
- vellum/workflows/expressions/contains.py +30 -0
- vellum/workflows/expressions/does_not_begin_with.py +31 -0
- vellum/workflows/expressions/does_not_contain.py +30 -0
- vellum/workflows/expressions/does_not_end_with.py +31 -0
- vellum/workflows/expressions/does_not_equal.py +25 -0
- vellum/workflows/expressions/ends_with.py +31 -0
- vellum/workflows/expressions/equals.py +25 -0
- vellum/workflows/expressions/greater_than.py +33 -0
- vellum/workflows/expressions/greater_than_or_equal_to.py +33 -0
- vellum/workflows/expressions/in_.py +31 -0
- vellum/workflows/expressions/is_blank.py +24 -0
- vellum/workflows/expressions/is_not_blank.py +24 -0
- vellum/workflows/expressions/is_not_null.py +21 -0
- vellum/workflows/expressions/is_not_undefined.py +22 -0
- vellum/workflows/expressions/is_null.py +21 -0
- vellum/workflows/expressions/is_undefined.py +22 -0
- vellum/workflows/expressions/less_than.py +33 -0
- vellum/workflows/expressions/less_than_or_equal_to.py +33 -0
- vellum/workflows/expressions/not_between.py +38 -0
- vellum/workflows/expressions/not_in.py +31 -0
- vellum/workflows/expressions/or_.py +32 -0
- vellum/workflows/graph/__init__.py +3 -0
- vellum/workflows/graph/graph.py +131 -0
- vellum/workflows/graph/tests/__init__.py +0 -0
- vellum/workflows/graph/tests/test_graph.py +437 -0
- vellum/workflows/inputs/__init__.py +5 -0
- vellum/workflows/inputs/base.py +55 -0
- vellum/workflows/logging.py +14 -0
- vellum/workflows/nodes/__init__.py +46 -0
- vellum/workflows/nodes/bases/__init__.py +7 -0
- vellum/workflows/nodes/bases/base.py +332 -0
- vellum/workflows/nodes/bases/base_subworkflow_node/__init__.py +5 -0
- vellum/workflows/nodes/bases/base_subworkflow_node/node.py +10 -0
- vellum/workflows/nodes/bases/tests/__init__.py +0 -0
- vellum/workflows/nodes/bases/tests/test_base_node.py +125 -0
- vellum/workflows/nodes/core/__init__.py +16 -0
- vellum/workflows/nodes/core/error_node/__init__.py +5 -0
- vellum/workflows/nodes/core/error_node/node.py +26 -0
- vellum/workflows/nodes/core/inline_subworkflow_node/__init__.py +5 -0
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py +73 -0
- vellum/workflows/nodes/core/map_node/__init__.py +5 -0
- vellum/workflows/nodes/core/map_node/node.py +147 -0
- vellum/workflows/nodes/core/map_node/tests/__init__.py +0 -0
- vellum/workflows/nodes/core/map_node/tests/test_node.py +65 -0
- vellum/workflows/nodes/core/retry_node/__init__.py +5 -0
- vellum/workflows/nodes/core/retry_node/node.py +106 -0
- vellum/workflows/nodes/core/retry_node/tests/__init__.py +0 -0
- vellum/workflows/nodes/core/retry_node/tests/test_node.py +93 -0
- vellum/workflows/nodes/core/templating_node/__init__.py +5 -0
- vellum/workflows/nodes/core/templating_node/custom_filters.py +12 -0
- vellum/workflows/nodes/core/templating_node/exceptions.py +2 -0
- vellum/workflows/nodes/core/templating_node/node.py +123 -0
- vellum/workflows/nodes/core/templating_node/render.py +55 -0
- vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py +21 -0
- vellum/workflows/nodes/core/try_node/__init__.py +5 -0
- vellum/workflows/nodes/core/try_node/node.py +110 -0
- vellum/workflows/nodes/core/try_node/tests/__init__.py +0 -0
- vellum/workflows/nodes/core/try_node/tests/test_node.py +82 -0
- vellum/workflows/nodes/displayable/__init__.py +31 -0
- vellum/workflows/nodes/displayable/api_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/api_node/node.py +44 -0
- vellum/workflows/nodes/displayable/bases/__init__.py +11 -0
- vellum/workflows/nodes/displayable/bases/api_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/bases/api_node/node.py +70 -0
- vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +60 -0
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/constants.py +13 -0
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +118 -0
- vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +98 -0
- vellum/workflows/nodes/displayable/bases/search_node.py +90 -0
- vellum/workflows/nodes/displayable/code_execution_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/code_execution_node/node.py +197 -0
- vellum/workflows/nodes/displayable/code_execution_node/tests/__init__.py +0 -0
- vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/__init__.py +0 -0
- vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/main.py +3 -0
- vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +111 -0
- vellum/workflows/nodes/displayable/code_execution_node/utils.py +10 -0
- vellum/workflows/nodes/displayable/conditional_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/conditional_node/node.py +25 -0
- vellum/workflows/nodes/displayable/final_output_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/final_output_node/node.py +43 -0
- vellum/workflows/nodes/displayable/guardrail_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/guardrail_node/node.py +97 -0
- vellum/workflows/nodes/displayable/inline_prompt_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/inline_prompt_node/node.py +41 -0
- vellum/workflows/nodes/displayable/merge_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/merge_node/node.py +10 -0
- vellum/workflows/nodes/displayable/prompt_deployment_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +45 -0
- vellum/workflows/nodes/displayable/search_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/search_node/node.py +26 -0
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/__init__.py +5 -0
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +156 -0
- vellum/workflows/nodes/displayable/tests/__init__.py +0 -0
- vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py +148 -0
- vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py +134 -0
- vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +80 -0
- vellum/workflows/nodes/utils.py +27 -0
- vellum/workflows/outputs/__init__.py +6 -0
- vellum/workflows/outputs/base.py +196 -0
- vellum/workflows/ports/__init__.py +7 -0
- vellum/workflows/ports/node_ports.py +75 -0
- vellum/workflows/ports/port.py +75 -0
- vellum/workflows/ports/utils.py +40 -0
- vellum/workflows/references/__init__.py +17 -0
- vellum/workflows/references/environment_variable.py +20 -0
- vellum/workflows/references/execution_count.py +20 -0
- vellum/workflows/references/external_input.py +49 -0
- vellum/workflows/references/input.py +7 -0
- vellum/workflows/references/lazy.py +55 -0
- vellum/workflows/references/node.py +43 -0
- vellum/workflows/references/output.py +78 -0
- vellum/workflows/references/state_value.py +23 -0
- vellum/workflows/references/vellum_secret.py +15 -0
- vellum/workflows/references/workflow_input.py +41 -0
- vellum/workflows/resolvers/__init__.py +5 -0
- vellum/workflows/resolvers/base.py +15 -0
- vellum/workflows/runner/__init__.py +5 -0
- vellum/workflows/runner/runner.py +588 -0
- vellum/workflows/runner/types.py +18 -0
- vellum/workflows/state/__init__.py +5 -0
- vellum/workflows/state/base.py +327 -0
- vellum/workflows/state/context.py +18 -0
- vellum/workflows/state/encoder.py +57 -0
- vellum/workflows/state/store.py +28 -0
- vellum/workflows/state/tests/__init__.py +0 -0
- vellum/workflows/state/tests/test_state.py +113 -0
- vellum/workflows/types/__init__.py +0 -0
- vellum/workflows/types/core.py +91 -0
- vellum/workflows/types/generics.py +14 -0
- vellum/workflows/types/stack.py +39 -0
- vellum/workflows/types/tests/__init__.py +0 -0
- vellum/workflows/types/tests/test_utils.py +76 -0
- vellum/workflows/types/utils.py +164 -0
- vellum/workflows/utils/__init__.py +0 -0
- vellum/workflows/utils/names.py +13 -0
- vellum/workflows/utils/tests/__init__.py +0 -0
- vellum/workflows/utils/tests/test_names.py +15 -0
- vellum/workflows/utils/tests/test_vellum_variables.py +25 -0
- vellum/workflows/utils/vellum_variables.py +81 -0
- vellum/workflows/vellum_client.py +18 -0
- vellum/workflows/workflows/__init__.py +5 -0
- vellum/workflows/workflows/base.py +365 -0
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.dist-info}/METADATA +2 -1
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.dist-info}/RECORD +245 -7
- vellum_cli/__init__.py +72 -0
- vellum_cli/aliased_group.py +103 -0
- vellum_cli/config.py +96 -0
- vellum_cli/image_push.py +112 -0
- vellum_cli/logger.py +36 -0
- vellum_cli/pull.py +73 -0
- vellum_cli/push.py +121 -0
- vellum_cli/tests/test_config.py +100 -0
- vellum_cli/tests/test_pull.py +152 -0
- vellum_ee/workflows/__init__.py +0 -0
- vellum_ee/workflows/display/__init__.py +0 -0
- vellum_ee/workflows/display/base.py +73 -0
- vellum_ee/workflows/display/nodes/__init__.py +4 -0
- vellum_ee/workflows/display/nodes/base_node_display.py +116 -0
- vellum_ee/workflows/display/nodes/base_node_vellum_display.py +36 -0
- vellum_ee/workflows/display/nodes/get_node_display_class.py +25 -0
- vellum_ee/workflows/display/nodes/tests/__init__.py +0 -0
- vellum_ee/workflows/display/nodes/tests/test_base_node_display.py +47 -0
- vellum_ee/workflows/display/nodes/types.py +18 -0
- vellum_ee/workflows/display/nodes/utils.py +33 -0
- vellum_ee/workflows/display/nodes/vellum/__init__.py +32 -0
- vellum_ee/workflows/display/nodes/vellum/api_node.py +205 -0
- vellum_ee/workflows/display/nodes/vellum/code_execution_node.py +71 -0
- vellum_ee/workflows/display/nodes/vellum/conditional_node.py +217 -0
- vellum_ee/workflows/display/nodes/vellum/final_output_node.py +61 -0
- vellum_ee/workflows/display/nodes/vellum/guardrail_node.py +49 -0
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +170 -0
- vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py +99 -0
- vellum_ee/workflows/display/nodes/vellum/map_node.py +100 -0
- vellum_ee/workflows/display/nodes/vellum/merge_node.py +48 -0
- vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +68 -0
- vellum_ee/workflows/display/nodes/vellum/search_node.py +193 -0
- vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py +58 -0
- vellum_ee/workflows/display/nodes/vellum/templating_node.py +67 -0
- vellum_ee/workflows/display/nodes/vellum/tests/__init__.py +0 -0
- vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +106 -0
- vellum_ee/workflows/display/nodes/vellum/try_node.py +38 -0
- vellum_ee/workflows/display/nodes/vellum/utils.py +76 -0
- vellum_ee/workflows/display/tests/__init__.py +0 -0
- vellum_ee/workflows/display/tests/workflow_serialization/__init__.py +0 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +426 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +607 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +1175 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_guardrail_node_serialization.py +235 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +511 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +372 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +272 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_prompt_deployment_serialization.py +289 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_deployment_serialization.py +354 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py +123 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py +84 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py +233 -0
- vellum_ee/workflows/display/types.py +46 -0
- vellum_ee/workflows/display/utils/__init__.py +0 -0
- vellum_ee/workflows/display/utils/tests/__init__.py +0 -0
- vellum_ee/workflows/display/utils/tests/test_uuids.py +16 -0
- vellum_ee/workflows/display/utils/uuids.py +24 -0
- vellum_ee/workflows/display/utils/vellum.py +121 -0
- vellum_ee/workflows/display/vellum.py +357 -0
- vellum_ee/workflows/display/workflows/__init__.py +5 -0
- vellum_ee/workflows/display/workflows/base_workflow_display.py +302 -0
- vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py +32 -0
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py +386 -0
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.dist-info}/LICENSE +0 -0
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.dist-info}/WHEEL +0 -0
- {vellum_ai-0.9.16rc2.dist-info → vellum_ai-0.9.16rc4.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
|
3
|
+
from vellum.workflows.events.workflow import WorkflowEvent
|
4
|
+
from vellum.workflows.state.base import BaseState
|
5
|
+
|
6
|
+
|
7
|
+
class BaseWorkflowEmitter(ABC):
|
8
|
+
@abstractmethod
|
9
|
+
def emit_event(self, event: WorkflowEvent) -> None:
|
10
|
+
pass
|
11
|
+
|
12
|
+
@abstractmethod
|
13
|
+
def snapshot_state(self, state: BaseState) -> None:
|
14
|
+
pass
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from enum import Enum
|
3
|
+
|
4
|
+
|
5
|
+
class VellumErrorCode(Enum):
|
6
|
+
INVALID_WORKFLOW = "INVALID_WORKFLOW"
|
7
|
+
INVALID_INPUTS = "INVALID_INPUTS"
|
8
|
+
INVALID_OUTPUTS = "INVALID_OUTPUTS"
|
9
|
+
INVALID_STATE = "INVALID_STATE"
|
10
|
+
INVALID_TEMPLATE = "INVALID_TEMPLATE"
|
11
|
+
INTERNAL_ERROR = "INTERNAL_ERROR"
|
12
|
+
PROVIDER_ERROR = "PROVIDER_ERROR"
|
13
|
+
USER_DEFINED_ERROR = "USER_DEFINED_ERROR"
|
14
|
+
WORKFLOW_CANCELLED = "WORKFLOW_CANCELLED"
|
15
|
+
|
16
|
+
|
17
|
+
@dataclass(frozen=True)
|
18
|
+
class VellumError:
|
19
|
+
message: str
|
20
|
+
code: VellumErrorCode
|
@@ -0,0 +1,31 @@
|
|
1
|
+
from .node import (
|
2
|
+
NodeEvent,
|
3
|
+
NodeExecutionFulfilledEvent,
|
4
|
+
NodeExecutionInitiatedEvent,
|
5
|
+
NodeExecutionRejectedEvent,
|
6
|
+
NodeExecutionStreamingEvent,
|
7
|
+
)
|
8
|
+
from .types import WorkflowEventType
|
9
|
+
from .workflow import (
|
10
|
+
WorkflowEvent,
|
11
|
+
WorkflowEventStream,
|
12
|
+
WorkflowExecutionFulfilledEvent,
|
13
|
+
WorkflowExecutionInitiatedEvent,
|
14
|
+
WorkflowExecutionRejectedEvent,
|
15
|
+
WorkflowExecutionStreamingEvent,
|
16
|
+
)
|
17
|
+
|
18
|
+
__all__ = [
|
19
|
+
"NodeExecutionFulfilledEvent",
|
20
|
+
"WorkflowExecutionFulfilledEvent",
|
21
|
+
"NodeExecutionInitiatedEvent",
|
22
|
+
"WorkflowExecutionInitiatedEvent",
|
23
|
+
"NodeEvent",
|
24
|
+
"NodeExecutionRejectedEvent",
|
25
|
+
"WorkflowExecutionRejectedEvent",
|
26
|
+
"NodeExecutionStreamingEvent",
|
27
|
+
"WorkflowExecutionStreamingEvent",
|
28
|
+
"WorkflowEvent",
|
29
|
+
"WorkflowEventStream",
|
30
|
+
"WorkflowEventType",
|
31
|
+
]
|
@@ -0,0 +1,125 @@
|
|
1
|
+
from typing import Any, Dict, Generic, Literal, Type, Union
|
2
|
+
|
3
|
+
from pydantic import field_serializer
|
4
|
+
|
5
|
+
from vellum.core.pydantic_utilities import UniversalBaseModel
|
6
|
+
|
7
|
+
from vellum.workflows.errors import VellumError
|
8
|
+
from vellum.workflows.expressions.accessor import AccessorExpression
|
9
|
+
from vellum.workflows.nodes.bases import BaseNode
|
10
|
+
from vellum.workflows.outputs.base import BaseOutput
|
11
|
+
from vellum.workflows.references.node import NodeReference
|
12
|
+
from vellum.workflows.types.generics import OutputsType
|
13
|
+
|
14
|
+
from .types import BaseEvent, default_serializer, serialize_type_encoder
|
15
|
+
|
16
|
+
|
17
|
+
class _BaseNodeExecutionBody(UniversalBaseModel):
|
18
|
+
node_definition: Type[BaseNode]
|
19
|
+
|
20
|
+
@field_serializer("node_definition")
|
21
|
+
def serialize_node_definition(self, node_definition: Type, _info: Any) -> Dict[str, Any]:
|
22
|
+
return serialize_type_encoder(node_definition)
|
23
|
+
|
24
|
+
|
25
|
+
class _BaseNodeEvent(BaseEvent):
|
26
|
+
body: _BaseNodeExecutionBody
|
27
|
+
|
28
|
+
@property
|
29
|
+
def node_definition(self) -> Type[BaseNode]:
|
30
|
+
return self.body.node_definition
|
31
|
+
|
32
|
+
|
33
|
+
NodeInputName = Union[NodeReference, AccessorExpression]
|
34
|
+
|
35
|
+
|
36
|
+
class NodeExecutionInitiatedBody(_BaseNodeExecutionBody):
|
37
|
+
inputs: Dict[NodeInputName, Any]
|
38
|
+
|
39
|
+
@field_serializer("inputs")
|
40
|
+
def serialize_inputs(self, inputs: Dict[NodeInputName, Any], _info: Any) -> Dict[str, Any]:
|
41
|
+
return default_serializer({descriptor.name: value for descriptor, value in inputs.items()})
|
42
|
+
|
43
|
+
|
44
|
+
class NodeExecutionInitiatedEvent(_BaseNodeEvent):
|
45
|
+
name: Literal["node.execution.initiated"] = "node.execution.initiated"
|
46
|
+
body: NodeExecutionInitiatedBody
|
47
|
+
|
48
|
+
@property
|
49
|
+
def inputs(self) -> Dict[NodeInputName, Any]:
|
50
|
+
return self.body.inputs
|
51
|
+
|
52
|
+
|
53
|
+
class NodeExecutionStreamingBody(_BaseNodeExecutionBody):
|
54
|
+
output: BaseOutput
|
55
|
+
|
56
|
+
@field_serializer("output")
|
57
|
+
def serialize_output(self, output: BaseOutput, _info: Any) -> Dict[str, Any]:
|
58
|
+
return default_serializer(output)
|
59
|
+
|
60
|
+
|
61
|
+
class NodeExecutionStreamingEvent(_BaseNodeEvent):
|
62
|
+
name: Literal["node.execution.streaming"] = "node.execution.streaming"
|
63
|
+
body: NodeExecutionStreamingBody
|
64
|
+
|
65
|
+
@property
|
66
|
+
def output(self) -> BaseOutput:
|
67
|
+
return self.body.output
|
68
|
+
|
69
|
+
|
70
|
+
class NodeExecutionFulfilledBody(_BaseNodeExecutionBody, Generic[OutputsType]):
|
71
|
+
outputs: OutputsType
|
72
|
+
|
73
|
+
@field_serializer("outputs")
|
74
|
+
def serialize_outputs(self, outputs: OutputsType, _info: Any) -> Dict[str, Any]:
|
75
|
+
return default_serializer(outputs)
|
76
|
+
|
77
|
+
|
78
|
+
class NodeExecutionFulfilledEvent(_BaseNodeEvent, Generic[OutputsType]):
|
79
|
+
name: Literal["node.execution.fulfilled"] = "node.execution.fulfilled"
|
80
|
+
body: NodeExecutionFulfilledBody[OutputsType]
|
81
|
+
|
82
|
+
@property
|
83
|
+
def outputs(self) -> OutputsType:
|
84
|
+
return self.body.outputs
|
85
|
+
|
86
|
+
|
87
|
+
class NodeExecutionRejectedBody(_BaseNodeExecutionBody):
|
88
|
+
error: VellumError
|
89
|
+
|
90
|
+
|
91
|
+
class NodeExecutionRejectedEvent(_BaseNodeEvent):
|
92
|
+
name: Literal["node.execution.rejected"] = "node.execution.rejected"
|
93
|
+
body: NodeExecutionRejectedBody
|
94
|
+
|
95
|
+
@property
|
96
|
+
def error(self) -> VellumError:
|
97
|
+
return self.body.error
|
98
|
+
|
99
|
+
|
100
|
+
class NodeExecutionPausedBody(_BaseNodeExecutionBody):
|
101
|
+
pass
|
102
|
+
|
103
|
+
|
104
|
+
class NodeExecutionPausedEvent(_BaseNodeEvent):
|
105
|
+
name: Literal["node.execution.paused"] = "node.execution.paused"
|
106
|
+
body: NodeExecutionPausedBody
|
107
|
+
|
108
|
+
|
109
|
+
class NodeExecutionResumedBody(_BaseNodeExecutionBody):
|
110
|
+
pass
|
111
|
+
|
112
|
+
|
113
|
+
class NodeExecutionResumedEvent(_BaseNodeEvent):
|
114
|
+
name: Literal["node.execution.resumed"] = "node.execution.resumed"
|
115
|
+
body: NodeExecutionResumedBody
|
116
|
+
|
117
|
+
|
118
|
+
NodeEvent = Union[
|
119
|
+
NodeExecutionInitiatedEvent,
|
120
|
+
NodeExecutionStreamingEvent,
|
121
|
+
NodeExecutionFulfilledEvent,
|
122
|
+
NodeExecutionRejectedEvent,
|
123
|
+
NodeExecutionPausedEvent,
|
124
|
+
NodeExecutionResumedEvent,
|
125
|
+
]
|
File without changes
|
@@ -0,0 +1,216 @@
|
|
1
|
+
import pytest
|
2
|
+
from datetime import datetime
|
3
|
+
import json
|
4
|
+
from uuid import UUID
|
5
|
+
|
6
|
+
from deepdiff import DeepDiff
|
7
|
+
|
8
|
+
from vellum.workflows.errors.types import VellumError, VellumErrorCode
|
9
|
+
from vellum.workflows.events.node import NodeExecutionInitiatedBody, NodeExecutionInitiatedEvent
|
10
|
+
from vellum.workflows.events.workflow import (
|
11
|
+
WorkflowExecutionFulfilledBody,
|
12
|
+
WorkflowExecutionFulfilledEvent,
|
13
|
+
WorkflowExecutionInitiatedBody,
|
14
|
+
WorkflowExecutionInitiatedEvent,
|
15
|
+
WorkflowExecutionRejectedBody,
|
16
|
+
WorkflowExecutionRejectedEvent,
|
17
|
+
WorkflowExecutionStreamingBody,
|
18
|
+
WorkflowExecutionStreamingEvent,
|
19
|
+
)
|
20
|
+
from vellum.workflows.inputs.base import BaseInputs
|
21
|
+
from vellum.workflows.nodes.bases.base import BaseNode
|
22
|
+
from vellum.workflows.outputs.base import BaseOutput
|
23
|
+
from vellum.workflows.state.base import BaseState
|
24
|
+
from vellum.workflows.workflows.base import BaseWorkflow
|
25
|
+
|
26
|
+
|
27
|
+
class MockInputs(BaseInputs):
|
28
|
+
foo: str
|
29
|
+
|
30
|
+
|
31
|
+
class MockNode(BaseNode):
|
32
|
+
node_foo = MockInputs.foo
|
33
|
+
|
34
|
+
class Outputs(BaseNode.Outputs):
|
35
|
+
example: str
|
36
|
+
|
37
|
+
|
38
|
+
class MockWorkflow(BaseWorkflow[MockInputs, BaseState]):
|
39
|
+
graph = MockNode
|
40
|
+
|
41
|
+
|
42
|
+
name_parts = __name__.split(".")
|
43
|
+
module_root = name_parts[: name_parts.index("events")]
|
44
|
+
|
45
|
+
|
46
|
+
@pytest.mark.parametrize(
|
47
|
+
["event", "expected_json"],
|
48
|
+
[
|
49
|
+
(
|
50
|
+
WorkflowExecutionInitiatedEvent(
|
51
|
+
id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
52
|
+
timestamp=datetime(2024, 1, 1, 12, 0, 0),
|
53
|
+
trace_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
54
|
+
span_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
55
|
+
body=WorkflowExecutionInitiatedBody(
|
56
|
+
workflow_definition=MockWorkflow,
|
57
|
+
inputs=MockInputs(foo="bar"),
|
58
|
+
),
|
59
|
+
),
|
60
|
+
{
|
61
|
+
"id": "123e4567-e89b-12d3-a456-426614174000",
|
62
|
+
"api_version": "2024-10-25",
|
63
|
+
"timestamp": "2024-01-01T12:00:00",
|
64
|
+
"trace_id": "123e4567-e89b-12d3-a456-426614174000",
|
65
|
+
"span_id": "123e4567-e89b-12d3-a456-426614174000",
|
66
|
+
"name": "workflow.execution.initiated",
|
67
|
+
"body": {
|
68
|
+
"workflow_definition": {
|
69
|
+
"name": "MockWorkflow",
|
70
|
+
"module": module_root + ["events", "tests", "test_event"],
|
71
|
+
},
|
72
|
+
"inputs": {
|
73
|
+
"foo": "bar",
|
74
|
+
},
|
75
|
+
},
|
76
|
+
},
|
77
|
+
),
|
78
|
+
(
|
79
|
+
NodeExecutionInitiatedEvent(
|
80
|
+
id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
81
|
+
timestamp=datetime(2024, 1, 1, 12, 0, 0),
|
82
|
+
trace_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
83
|
+
span_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
84
|
+
body=NodeExecutionInitiatedBody(
|
85
|
+
node_definition=MockNode,
|
86
|
+
inputs={
|
87
|
+
MockNode.node_foo: "bar",
|
88
|
+
},
|
89
|
+
),
|
90
|
+
),
|
91
|
+
{
|
92
|
+
"id": "123e4567-e89b-12d3-a456-426614174000",
|
93
|
+
"api_version": "2024-10-25",
|
94
|
+
"timestamp": "2024-01-01T12:00:00",
|
95
|
+
"trace_id": "123e4567-e89b-12d3-a456-426614174000",
|
96
|
+
"span_id": "123e4567-e89b-12d3-a456-426614174000",
|
97
|
+
"name": "node.execution.initiated",
|
98
|
+
"body": {
|
99
|
+
"node_definition": {
|
100
|
+
"name": "MockNode",
|
101
|
+
"module": module_root + ["events", "tests", "test_event"],
|
102
|
+
},
|
103
|
+
"inputs": {
|
104
|
+
"node_foo": "bar",
|
105
|
+
},
|
106
|
+
},
|
107
|
+
},
|
108
|
+
),
|
109
|
+
(
|
110
|
+
WorkflowExecutionStreamingEvent(
|
111
|
+
id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
112
|
+
timestamp=datetime(2024, 1, 1, 12, 0, 0),
|
113
|
+
trace_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
114
|
+
span_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
115
|
+
body=WorkflowExecutionStreamingBody(
|
116
|
+
workflow_definition=MockWorkflow,
|
117
|
+
output=BaseOutput(
|
118
|
+
name="example",
|
119
|
+
value="foo",
|
120
|
+
),
|
121
|
+
),
|
122
|
+
),
|
123
|
+
{
|
124
|
+
"id": "123e4567-e89b-12d3-a456-426614174000",
|
125
|
+
"api_version": "2024-10-25",
|
126
|
+
"timestamp": "2024-01-01T12:00:00",
|
127
|
+
"trace_id": "123e4567-e89b-12d3-a456-426614174000",
|
128
|
+
"span_id": "123e4567-e89b-12d3-a456-426614174000",
|
129
|
+
"name": "workflow.execution.streaming",
|
130
|
+
"body": {
|
131
|
+
"workflow_definition": {
|
132
|
+
"name": "MockWorkflow",
|
133
|
+
"module": module_root + ["events", "tests", "test_event"],
|
134
|
+
},
|
135
|
+
"output": {
|
136
|
+
"name": "example",
|
137
|
+
"value": "foo",
|
138
|
+
},
|
139
|
+
},
|
140
|
+
},
|
141
|
+
),
|
142
|
+
(
|
143
|
+
WorkflowExecutionFulfilledEvent(
|
144
|
+
id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
145
|
+
timestamp=datetime(2024, 1, 1, 12, 0, 0),
|
146
|
+
trace_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
147
|
+
span_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
148
|
+
body=WorkflowExecutionFulfilledBody(
|
149
|
+
workflow_definition=MockWorkflow,
|
150
|
+
outputs=MockNode.Outputs(
|
151
|
+
example="foo",
|
152
|
+
),
|
153
|
+
),
|
154
|
+
),
|
155
|
+
{
|
156
|
+
"id": "123e4567-e89b-12d3-a456-426614174000",
|
157
|
+
"api_version": "2024-10-25",
|
158
|
+
"timestamp": "2024-01-01T12:00:00",
|
159
|
+
"trace_id": "123e4567-e89b-12d3-a456-426614174000",
|
160
|
+
"span_id": "123e4567-e89b-12d3-a456-426614174000",
|
161
|
+
"name": "workflow.execution.fulfilled",
|
162
|
+
"body": {
|
163
|
+
"workflow_definition": {
|
164
|
+
"name": "MockWorkflow",
|
165
|
+
"module": module_root + ["events", "tests", "test_event"],
|
166
|
+
},
|
167
|
+
"outputs": {
|
168
|
+
"example": "foo",
|
169
|
+
},
|
170
|
+
},
|
171
|
+
},
|
172
|
+
),
|
173
|
+
(
|
174
|
+
WorkflowExecutionRejectedEvent(
|
175
|
+
id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
176
|
+
timestamp=datetime(2024, 1, 1, 12, 0, 0),
|
177
|
+
trace_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
178
|
+
span_id=UUID("123e4567-e89b-12d3-a456-426614174000"),
|
179
|
+
body=WorkflowExecutionRejectedBody(
|
180
|
+
workflow_definition=MockWorkflow,
|
181
|
+
error=VellumError(
|
182
|
+
message="Workflow failed",
|
183
|
+
code=VellumErrorCode.USER_DEFINED_ERROR,
|
184
|
+
),
|
185
|
+
),
|
186
|
+
),
|
187
|
+
{
|
188
|
+
"id": "123e4567-e89b-12d3-a456-426614174000",
|
189
|
+
"api_version": "2024-10-25",
|
190
|
+
"timestamp": "2024-01-01T12:00:00",
|
191
|
+
"trace_id": "123e4567-e89b-12d3-a456-426614174000",
|
192
|
+
"span_id": "123e4567-e89b-12d3-a456-426614174000",
|
193
|
+
"name": "workflow.execution.rejected",
|
194
|
+
"body": {
|
195
|
+
"workflow_definition": {
|
196
|
+
"name": "MockWorkflow",
|
197
|
+
"module": module_root + ["events", "tests", "test_event"],
|
198
|
+
},
|
199
|
+
"error": {
|
200
|
+
"message": "Workflow failed",
|
201
|
+
"code": "USER_DEFINED_ERROR",
|
202
|
+
},
|
203
|
+
},
|
204
|
+
},
|
205
|
+
),
|
206
|
+
],
|
207
|
+
ids=[
|
208
|
+
"workflow.execution.initiated",
|
209
|
+
"node.execution.initiated",
|
210
|
+
"workflow.execution.streaming",
|
211
|
+
"workflow.execution.fulfilled",
|
212
|
+
"workflow.execution.rejected",
|
213
|
+
],
|
214
|
+
)
|
215
|
+
def test_event_serialization(event, expected_json):
|
216
|
+
assert not DeepDiff(json.loads(event.model_dump_json()), expected_json)
|
@@ -0,0 +1,52 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
from enum import Enum
|
3
|
+
import json
|
4
|
+
from uuid import UUID, uuid4
|
5
|
+
from typing import Any, Dict, Literal
|
6
|
+
|
7
|
+
from pydantic import Field
|
8
|
+
|
9
|
+
from vellum.core.pydantic_utilities import UniversalBaseModel
|
10
|
+
|
11
|
+
from vellum.workflows.state.encoder import DefaultStateEncoder
|
12
|
+
from vellum.workflows.types.utils import datetime_now
|
13
|
+
|
14
|
+
|
15
|
+
class WorkflowEventType(Enum):
|
16
|
+
NODE = "NODE"
|
17
|
+
WORKFLOW = "WORKFLOW"
|
18
|
+
|
19
|
+
|
20
|
+
def default_datetime_factory() -> datetime:
|
21
|
+
"""
|
22
|
+
Makes it possible to mock the datetime factory for testing.
|
23
|
+
"""
|
24
|
+
|
25
|
+
return datetime_now()
|
26
|
+
|
27
|
+
|
28
|
+
excluded_modules = {"typing", "builtins"}
|
29
|
+
|
30
|
+
|
31
|
+
def serialize_type_encoder(obj: type) -> Dict[str, Any]:
|
32
|
+
return {
|
33
|
+
"name": obj.__name__,
|
34
|
+
"module": obj.__module__.split("."),
|
35
|
+
}
|
36
|
+
|
37
|
+
|
38
|
+
def default_serializer(obj: Any) -> Any:
|
39
|
+
return json.loads(
|
40
|
+
json.dumps(
|
41
|
+
obj,
|
42
|
+
cls=DefaultStateEncoder,
|
43
|
+
)
|
44
|
+
)
|
45
|
+
|
46
|
+
|
47
|
+
class BaseEvent(UniversalBaseModel):
|
48
|
+
id: UUID = Field(default_factory=uuid4)
|
49
|
+
timestamp: datetime = Field(default_factory=default_datetime_factory)
|
50
|
+
api_version: Literal["2024-10-25"] = "2024-10-25"
|
51
|
+
trace_id: UUID
|
52
|
+
span_id: UUID
|
@@ -0,0 +1,139 @@
|
|
1
|
+
from typing import TYPE_CHECKING, Any, Dict, Generator, Generic, Iterable, Literal, Type, Union
|
2
|
+
|
3
|
+
from pydantic import field_serializer
|
4
|
+
|
5
|
+
from vellum.core.pydantic_utilities import UniversalBaseModel
|
6
|
+
|
7
|
+
from vellum.workflows.errors import VellumError
|
8
|
+
from vellum.workflows.outputs.base import BaseOutput
|
9
|
+
from vellum.workflows.references import ExternalInputReference
|
10
|
+
from vellum.workflows.types.generics import OutputsType, WorkflowInputsType
|
11
|
+
|
12
|
+
from .node import (
|
13
|
+
NodeExecutionFulfilledEvent,
|
14
|
+
NodeExecutionInitiatedEvent,
|
15
|
+
NodeExecutionPausedEvent,
|
16
|
+
NodeExecutionRejectedEvent,
|
17
|
+
NodeExecutionResumedEvent,
|
18
|
+
NodeExecutionStreamingEvent,
|
19
|
+
)
|
20
|
+
from .types import BaseEvent, default_serializer, serialize_type_encoder
|
21
|
+
|
22
|
+
if TYPE_CHECKING:
|
23
|
+
from vellum.workflows.workflows.base import BaseWorkflow
|
24
|
+
|
25
|
+
|
26
|
+
class _BaseWorkflowExecutionBody(UniversalBaseModel):
|
27
|
+
workflow_definition: Type["BaseWorkflow"]
|
28
|
+
|
29
|
+
@field_serializer("workflow_definition")
|
30
|
+
def serialize_workflow_definition(self, workflow_definition: Type, _info: Any) -> Dict[str, Any]:
|
31
|
+
return serialize_type_encoder(workflow_definition)
|
32
|
+
|
33
|
+
|
34
|
+
class WorkflowExecutionInitiatedBody(_BaseWorkflowExecutionBody, Generic[WorkflowInputsType]):
|
35
|
+
inputs: WorkflowInputsType
|
36
|
+
|
37
|
+
@field_serializer("inputs")
|
38
|
+
def serialize_inputs(self, inputs: WorkflowInputsType, _info: Any) -> Dict[str, Any]:
|
39
|
+
return default_serializer(inputs)
|
40
|
+
|
41
|
+
|
42
|
+
class WorkflowExecutionInitiatedEvent(BaseEvent, Generic[WorkflowInputsType]):
|
43
|
+
name: Literal["workflow.execution.initiated"] = "workflow.execution.initiated"
|
44
|
+
body: WorkflowExecutionInitiatedBody[WorkflowInputsType]
|
45
|
+
|
46
|
+
@property
|
47
|
+
def inputs(self) -> WorkflowInputsType:
|
48
|
+
return self.body.inputs
|
49
|
+
|
50
|
+
|
51
|
+
class WorkflowExecutionStreamingBody(_BaseWorkflowExecutionBody):
|
52
|
+
output: BaseOutput
|
53
|
+
|
54
|
+
@field_serializer("output")
|
55
|
+
def serialize_output(self, output: BaseOutput, _info: Any) -> Dict[str, Any]:
|
56
|
+
return default_serializer(output)
|
57
|
+
|
58
|
+
|
59
|
+
class WorkflowExecutionStreamingEvent(BaseEvent):
|
60
|
+
name: Literal["workflow.execution.streaming"] = "workflow.execution.streaming"
|
61
|
+
body: WorkflowExecutionStreamingBody
|
62
|
+
|
63
|
+
@property
|
64
|
+
def output(self) -> BaseOutput:
|
65
|
+
return self.body.output
|
66
|
+
|
67
|
+
|
68
|
+
class WorkflowExecutionFulfilledBody(_BaseWorkflowExecutionBody, Generic[OutputsType]):
|
69
|
+
outputs: OutputsType
|
70
|
+
|
71
|
+
@field_serializer("outputs")
|
72
|
+
def serialize_outputs(self, outputs: OutputsType, _info: Any) -> Dict[str, Any]:
|
73
|
+
return default_serializer(outputs)
|
74
|
+
|
75
|
+
|
76
|
+
class WorkflowExecutionFulfilledEvent(BaseEvent, Generic[OutputsType]):
|
77
|
+
name: Literal["workflow.execution.fulfilled"] = "workflow.execution.fulfilled"
|
78
|
+
body: WorkflowExecutionFulfilledBody[OutputsType]
|
79
|
+
|
80
|
+
@property
|
81
|
+
def outputs(self) -> OutputsType:
|
82
|
+
return self.body.outputs
|
83
|
+
|
84
|
+
|
85
|
+
class WorkflowExecutionRejectedBody(_BaseWorkflowExecutionBody):
|
86
|
+
error: VellumError
|
87
|
+
|
88
|
+
|
89
|
+
class WorkflowExecutionRejectedEvent(BaseEvent):
|
90
|
+
name: Literal["workflow.execution.rejected"] = "workflow.execution.rejected"
|
91
|
+
body: WorkflowExecutionRejectedBody
|
92
|
+
|
93
|
+
@property
|
94
|
+
def error(self) -> VellumError:
|
95
|
+
return self.body.error
|
96
|
+
|
97
|
+
|
98
|
+
class WorkflowExecutionPausedBody(_BaseWorkflowExecutionBody):
|
99
|
+
external_inputs: Iterable[ExternalInputReference]
|
100
|
+
|
101
|
+
|
102
|
+
class WorkflowExecutionPausedEvent(BaseEvent):
|
103
|
+
name: Literal["workflow.execution.paused"] = "workflow.execution.paused"
|
104
|
+
body: WorkflowExecutionPausedBody
|
105
|
+
|
106
|
+
@property
|
107
|
+
def external_inputs(self) -> Iterable[ExternalInputReference]:
|
108
|
+
return self.body.external_inputs
|
109
|
+
|
110
|
+
|
111
|
+
class WorkflowExecutionResumedBody(_BaseWorkflowExecutionBody):
|
112
|
+
pass
|
113
|
+
|
114
|
+
|
115
|
+
class WorkflowExecutionResumedEvent(BaseEvent):
|
116
|
+
name: Literal["workflow.execution.resumed"] = "workflow.execution.resumed"
|
117
|
+
body: WorkflowExecutionResumedBody
|
118
|
+
|
119
|
+
|
120
|
+
GenericWorkflowEvent = Union[
|
121
|
+
WorkflowExecutionStreamingEvent,
|
122
|
+
WorkflowExecutionRejectedEvent,
|
123
|
+
WorkflowExecutionPausedEvent,
|
124
|
+
WorkflowExecutionResumedEvent,
|
125
|
+
NodeExecutionInitiatedEvent,
|
126
|
+
NodeExecutionStreamingEvent,
|
127
|
+
NodeExecutionFulfilledEvent,
|
128
|
+
NodeExecutionRejectedEvent,
|
129
|
+
NodeExecutionPausedEvent,
|
130
|
+
NodeExecutionResumedEvent,
|
131
|
+
]
|
132
|
+
|
133
|
+
WorkflowEvent = Union[
|
134
|
+
GenericWorkflowEvent,
|
135
|
+
WorkflowExecutionInitiatedEvent,
|
136
|
+
WorkflowExecutionFulfilledEvent,
|
137
|
+
]
|
138
|
+
|
139
|
+
WorkflowEventStream = Generator[WorkflowEvent, None, None]
|
@@ -0,0 +1,15 @@
|
|
1
|
+
from vellum.workflows.errors import VellumError, VellumErrorCode
|
2
|
+
|
3
|
+
|
4
|
+
class NodeException(Exception):
|
5
|
+
def __init__(self, message: str, code: VellumErrorCode):
|
6
|
+
self.message = message
|
7
|
+
self.code = code
|
8
|
+
super().__init__(message)
|
9
|
+
|
10
|
+
@property
|
11
|
+
def error(self) -> VellumError:
|
12
|
+
return VellumError(
|
13
|
+
message=self.message,
|
14
|
+
code=self.code,
|
15
|
+
)
|
File without changes
|