vellum-ai 0.14.6__py3-none-any.whl → 0.14.8__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 +14 -0
- vellum/client/core/client_wrapper.py +1 -1
- vellum/client/types/__init__.py +14 -0
- vellum/client/types/array_chat_message_content_item.py +6 -1
- vellum/client/types/array_chat_message_content_item_request.py +2 -0
- vellum/client/types/chat_message_content.py +2 -0
- vellum/client/types/chat_message_content_request.py +2 -0
- vellum/client/types/document_chat_message_content.py +25 -0
- vellum/client/types/document_chat_message_content_request.py +25 -0
- vellum/client/types/document_prompt_block.py +29 -0
- vellum/client/types/document_vellum_value.py +25 -0
- vellum/client/types/document_vellum_value_request.py +25 -0
- vellum/client/types/prompt_block.py +2 -0
- vellum/client/types/vellum_document.py +20 -0
- vellum/client/types/vellum_document_request.py +20 -0
- vellum/client/types/vellum_value.py +2 -0
- vellum/client/types/vellum_value_request.py +2 -0
- vellum/client/types/vellum_variable_type.py +1 -0
- vellum/types/document_chat_message_content.py +3 -0
- vellum/types/document_chat_message_content_request.py +3 -0
- vellum/types/document_prompt_block.py +3 -0
- vellum/types/document_vellum_value.py +3 -0
- vellum/types/document_vellum_value_request.py +3 -0
- vellum/types/vellum_document.py +3 -0
- vellum/types/vellum_document_request.py +3 -0
- vellum/workflows/exceptions.py +18 -0
- vellum/workflows/inputs/base.py +27 -1
- vellum/workflows/inputs/tests/__init__.py +0 -0
- vellum/workflows/inputs/tests/test_inputs.py +49 -0
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py +1 -1
- vellum/workflows/nodes/core/map_node/node.py +7 -7
- vellum/workflows/nodes/core/try_node/node.py +1 -1
- vellum/workflows/nodes/displayable/api_node/tests/test_api_node.py +33 -0
- vellum/workflows/nodes/displayable/bases/api_node/node.py +1 -1
- vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +2 -2
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +5 -3
- vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +5 -4
- vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py +4 -4
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +39 -15
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py +142 -0
- vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +3 -1
- vellum/workflows/outputs/base.py +1 -1
- vellum/workflows/runner/runner.py +16 -10
- vellum/workflows/state/context.py +7 -7
- vellum/workflows/workflows/base.py +16 -5
- vellum/workflows/workflows/tests/test_base_workflow.py +131 -40
- {vellum_ai-0.14.6.dist-info → vellum_ai-0.14.8.dist-info}/METADATA +1 -1
- {vellum_ai-0.14.6.dist-info → vellum_ai-0.14.8.dist-info}/RECORD +65 -47
- vellum_cli/__init__.py +43 -0
- vellum_cli/config.py +1 -0
- vellum_cli/init.py +132 -0
- vellum_cli/pull.py +7 -3
- vellum_cli/tests/test_init.py +473 -0
- vellum_cli/tests/test_pull.py +135 -0
- vellum_cli/tests/test_push.py +1 -0
- vellum_ee/workflows/display/nodes/base_node_display.py +4 -4
- vellum_ee/workflows/display/tests/test_vellum_workflow_display.py +83 -0
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +118 -3
- vellum_ee/workflows/display/vellum.py +0 -4
- vellum_ee/workflows/display/workflows/base_workflow_display.py +46 -13
- vellum_ee/workflows/display/workflows/tests/test_workflow_display.py +29 -0
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py +12 -0
- {vellum_ai-0.14.6.dist-info → vellum_ai-0.14.8.dist-info}/LICENSE +0 -0
- {vellum_ai-0.14.6.dist-info → vellum_ai-0.14.8.dist-info}/WHEEL +0 -0
- {vellum_ai-0.14.6.dist-info → vellum_ai-0.14.8.dist-info}/entry_points.txt +0 -0
vellum/__init__.py
CHANGED
@@ -74,6 +74,8 @@ from .types import (
|
|
74
74
|
DeploymentReleaseTagDeploymentHistoryItem,
|
75
75
|
DeploymentReleaseTagRead,
|
76
76
|
DockerServiceToken,
|
77
|
+
DocumentChatMessageContent,
|
78
|
+
DocumentChatMessageContentRequest,
|
77
79
|
DocumentDocumentToDocumentIndex,
|
78
80
|
DocumentIndexChunking,
|
79
81
|
DocumentIndexChunkingRequest,
|
@@ -81,8 +83,11 @@ from .types import (
|
|
81
83
|
DocumentIndexIndexingConfigRequest,
|
82
84
|
DocumentIndexRead,
|
83
85
|
DocumentProcessingState,
|
86
|
+
DocumentPromptBlock,
|
84
87
|
DocumentRead,
|
85
88
|
DocumentStatus,
|
89
|
+
DocumentVellumValue,
|
90
|
+
DocumentVellumValueRequest,
|
86
91
|
EnrichedNormalizedCompletion,
|
87
92
|
EntityStatus,
|
88
93
|
EntityVisibility,
|
@@ -438,6 +443,8 @@ from .types import (
|
|
438
443
|
VariablePromptBlock,
|
439
444
|
VellumAudio,
|
440
445
|
VellumAudioRequest,
|
446
|
+
VellumDocument,
|
447
|
+
VellumDocumentRequest,
|
441
448
|
VellumError,
|
442
449
|
VellumErrorCodeEnum,
|
443
450
|
VellumErrorRequest,
|
@@ -607,6 +614,8 @@ __all__ = [
|
|
607
614
|
"DeploymentReleaseTagRead",
|
608
615
|
"DeploymentsListRequestStatus",
|
609
616
|
"DockerServiceToken",
|
617
|
+
"DocumentChatMessageContent",
|
618
|
+
"DocumentChatMessageContentRequest",
|
610
619
|
"DocumentDocumentToDocumentIndex",
|
611
620
|
"DocumentIndexChunking",
|
612
621
|
"DocumentIndexChunkingRequest",
|
@@ -615,8 +624,11 @@ __all__ = [
|
|
615
624
|
"DocumentIndexRead",
|
616
625
|
"DocumentIndexesListRequestStatus",
|
617
626
|
"DocumentProcessingState",
|
627
|
+
"DocumentPromptBlock",
|
618
628
|
"DocumentRead",
|
619
629
|
"DocumentStatus",
|
630
|
+
"DocumentVellumValue",
|
631
|
+
"DocumentVellumValueRequest",
|
620
632
|
"EnrichedNormalizedCompletion",
|
621
633
|
"EntityStatus",
|
622
634
|
"EntityVisibility",
|
@@ -980,6 +992,8 @@ __all__ = [
|
|
980
992
|
"Vellum",
|
981
993
|
"VellumAudio",
|
982
994
|
"VellumAudioRequest",
|
995
|
+
"VellumDocument",
|
996
|
+
"VellumDocumentRequest",
|
983
997
|
"VellumEnvironment",
|
984
998
|
"VellumError",
|
985
999
|
"VellumErrorCodeEnum",
|
@@ -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.8",
|
22
22
|
}
|
23
23
|
headers["X_API_KEY"] = self.api_key
|
24
24
|
return headers
|
vellum/client/types/__init__.py
CHANGED
@@ -78,6 +78,8 @@ from .deployment_read import DeploymentRead
|
|
78
78
|
from .deployment_release_tag_deployment_history_item import DeploymentReleaseTagDeploymentHistoryItem
|
79
79
|
from .deployment_release_tag_read import DeploymentReleaseTagRead
|
80
80
|
from .docker_service_token import DockerServiceToken
|
81
|
+
from .document_chat_message_content import DocumentChatMessageContent
|
82
|
+
from .document_chat_message_content_request import DocumentChatMessageContentRequest
|
81
83
|
from .document_document_to_document_index import DocumentDocumentToDocumentIndex
|
82
84
|
from .document_index_chunking import DocumentIndexChunking
|
83
85
|
from .document_index_chunking_request import DocumentIndexChunkingRequest
|
@@ -85,8 +87,11 @@ from .document_index_indexing_config import DocumentIndexIndexingConfig
|
|
85
87
|
from .document_index_indexing_config_request import DocumentIndexIndexingConfigRequest
|
86
88
|
from .document_index_read import DocumentIndexRead
|
87
89
|
from .document_processing_state import DocumentProcessingState
|
90
|
+
from .document_prompt_block import DocumentPromptBlock
|
88
91
|
from .document_read import DocumentRead
|
89
92
|
from .document_status import DocumentStatus
|
93
|
+
from .document_vellum_value import DocumentVellumValue
|
94
|
+
from .document_vellum_value_request import DocumentVellumValueRequest
|
90
95
|
from .enriched_normalized_completion import EnrichedNormalizedCompletion
|
91
96
|
from .entity_status import EntityStatus
|
92
97
|
from .entity_visibility import EntityVisibility
|
@@ -462,6 +467,8 @@ from .upsert_test_suite_test_case_request import UpsertTestSuiteTestCaseRequest
|
|
462
467
|
from .variable_prompt_block import VariablePromptBlock
|
463
468
|
from .vellum_audio import VellumAudio
|
464
469
|
from .vellum_audio_request import VellumAudioRequest
|
470
|
+
from .vellum_document import VellumDocument
|
471
|
+
from .vellum_document_request import VellumDocumentRequest
|
465
472
|
from .vellum_error import VellumError
|
466
473
|
from .vellum_error_code_enum import VellumErrorCodeEnum
|
467
474
|
from .vellum_error_request import VellumErrorRequest
|
@@ -596,6 +603,8 @@ __all__ = [
|
|
596
603
|
"DeploymentReleaseTagDeploymentHistoryItem",
|
597
604
|
"DeploymentReleaseTagRead",
|
598
605
|
"DockerServiceToken",
|
606
|
+
"DocumentChatMessageContent",
|
607
|
+
"DocumentChatMessageContentRequest",
|
599
608
|
"DocumentDocumentToDocumentIndex",
|
600
609
|
"DocumentIndexChunking",
|
601
610
|
"DocumentIndexChunkingRequest",
|
@@ -603,8 +612,11 @@ __all__ = [
|
|
603
612
|
"DocumentIndexIndexingConfigRequest",
|
604
613
|
"DocumentIndexRead",
|
605
614
|
"DocumentProcessingState",
|
615
|
+
"DocumentPromptBlock",
|
606
616
|
"DocumentRead",
|
607
617
|
"DocumentStatus",
|
618
|
+
"DocumentVellumValue",
|
619
|
+
"DocumentVellumValueRequest",
|
608
620
|
"EnrichedNormalizedCompletion",
|
609
621
|
"EntityStatus",
|
610
622
|
"EntityVisibility",
|
@@ -960,6 +972,8 @@ __all__ = [
|
|
960
972
|
"VariablePromptBlock",
|
961
973
|
"VellumAudio",
|
962
974
|
"VellumAudioRequest",
|
975
|
+
"VellumDocument",
|
976
|
+
"VellumDocumentRequest",
|
963
977
|
"VellumError",
|
964
978
|
"VellumErrorCodeEnum",
|
965
979
|
"VellumErrorRequest",
|
@@ -5,7 +5,12 @@ from .string_chat_message_content import StringChatMessageContent
|
|
5
5
|
from .function_call_chat_message_content import FunctionCallChatMessageContent
|
6
6
|
from .image_chat_message_content import ImageChatMessageContent
|
7
7
|
from .audio_chat_message_content import AudioChatMessageContent
|
8
|
+
from .document_chat_message_content import DocumentChatMessageContent
|
8
9
|
|
9
10
|
ArrayChatMessageContentItem = typing.Union[
|
10
|
-
StringChatMessageContent,
|
11
|
+
StringChatMessageContent,
|
12
|
+
FunctionCallChatMessageContent,
|
13
|
+
ImageChatMessageContent,
|
14
|
+
AudioChatMessageContent,
|
15
|
+
DocumentChatMessageContent,
|
11
16
|
]
|
@@ -5,10 +5,12 @@ from .string_chat_message_content_request import StringChatMessageContentRequest
|
|
5
5
|
from .function_call_chat_message_content_request import FunctionCallChatMessageContentRequest
|
6
6
|
from .image_chat_message_content_request import ImageChatMessageContentRequest
|
7
7
|
from .audio_chat_message_content_request import AudioChatMessageContentRequest
|
8
|
+
from .document_chat_message_content_request import DocumentChatMessageContentRequest
|
8
9
|
|
9
10
|
ArrayChatMessageContentItemRequest = typing.Union[
|
10
11
|
StringChatMessageContentRequest,
|
11
12
|
FunctionCallChatMessageContentRequest,
|
12
13
|
ImageChatMessageContentRequest,
|
13
14
|
AudioChatMessageContentRequest,
|
15
|
+
DocumentChatMessageContentRequest,
|
14
16
|
]
|
@@ -6,6 +6,7 @@ from .function_call_chat_message_content import FunctionCallChatMessageContent
|
|
6
6
|
from .array_chat_message_content import ArrayChatMessageContent
|
7
7
|
from .image_chat_message_content import ImageChatMessageContent
|
8
8
|
from .audio_chat_message_content import AudioChatMessageContent
|
9
|
+
from .document_chat_message_content import DocumentChatMessageContent
|
9
10
|
|
10
11
|
ChatMessageContent = typing.Union[
|
11
12
|
StringChatMessageContent,
|
@@ -13,4 +14,5 @@ ChatMessageContent = typing.Union[
|
|
13
14
|
ArrayChatMessageContent,
|
14
15
|
ImageChatMessageContent,
|
15
16
|
AudioChatMessageContent,
|
17
|
+
DocumentChatMessageContent,
|
16
18
|
]
|
@@ -6,6 +6,7 @@ from .function_call_chat_message_content_request import FunctionCallChatMessageC
|
|
6
6
|
from .array_chat_message_content_request import ArrayChatMessageContentRequest
|
7
7
|
from .image_chat_message_content_request import ImageChatMessageContentRequest
|
8
8
|
from .audio_chat_message_content_request import AudioChatMessageContentRequest
|
9
|
+
from .document_chat_message_content_request import DocumentChatMessageContentRequest
|
9
10
|
|
10
11
|
ChatMessageContentRequest = typing.Union[
|
11
12
|
StringChatMessageContentRequest,
|
@@ -13,4 +14,5 @@ ChatMessageContentRequest = typing.Union[
|
|
13
14
|
ArrayChatMessageContentRequest,
|
14
15
|
ImageChatMessageContentRequest,
|
15
16
|
AudioChatMessageContentRequest,
|
17
|
+
DocumentChatMessageContentRequest,
|
16
18
|
]
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
2
|
+
|
3
|
+
from ..core.pydantic_utilities import UniversalBaseModel
|
4
|
+
import typing
|
5
|
+
from .vellum_document import VellumDocument
|
6
|
+
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
7
|
+
import pydantic
|
8
|
+
|
9
|
+
|
10
|
+
class DocumentChatMessageContent(UniversalBaseModel):
|
11
|
+
"""
|
12
|
+
A document value that is used in a chat message.
|
13
|
+
"""
|
14
|
+
|
15
|
+
type: typing.Literal["DOCUMENT"] = "DOCUMENT"
|
16
|
+
value: VellumDocument
|
17
|
+
|
18
|
+
if IS_PYDANTIC_V2:
|
19
|
+
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
20
|
+
else:
|
21
|
+
|
22
|
+
class Config:
|
23
|
+
frozen = True
|
24
|
+
smart_union = True
|
25
|
+
extra = pydantic.Extra.allow
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
2
|
+
|
3
|
+
from ..core.pydantic_utilities import UniversalBaseModel
|
4
|
+
import typing
|
5
|
+
from .vellum_document_request import VellumDocumentRequest
|
6
|
+
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
7
|
+
import pydantic
|
8
|
+
|
9
|
+
|
10
|
+
class DocumentChatMessageContentRequest(UniversalBaseModel):
|
11
|
+
"""
|
12
|
+
A document value that is used in a chat message.
|
13
|
+
"""
|
14
|
+
|
15
|
+
type: typing.Literal["DOCUMENT"] = "DOCUMENT"
|
16
|
+
value: VellumDocumentRequest
|
17
|
+
|
18
|
+
if IS_PYDANTIC_V2:
|
19
|
+
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
20
|
+
else:
|
21
|
+
|
22
|
+
class Config:
|
23
|
+
frozen = True
|
24
|
+
smart_union = True
|
25
|
+
extra = pydantic.Extra.allow
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
2
|
+
|
3
|
+
from ..core.pydantic_utilities import UniversalBaseModel
|
4
|
+
import typing
|
5
|
+
from .prompt_block_state import PromptBlockState
|
6
|
+
from .ephemeral_prompt_cache_config import EphemeralPromptCacheConfig
|
7
|
+
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
8
|
+
import pydantic
|
9
|
+
|
10
|
+
|
11
|
+
class DocumentPromptBlock(UniversalBaseModel):
|
12
|
+
"""
|
13
|
+
A block that represents a document in a prompt template.
|
14
|
+
"""
|
15
|
+
|
16
|
+
block_type: typing.Literal["DOCUMENT"] = "DOCUMENT"
|
17
|
+
state: typing.Optional[PromptBlockState] = None
|
18
|
+
cache_config: typing.Optional[EphemeralPromptCacheConfig] = None
|
19
|
+
src: str
|
20
|
+
metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = None
|
21
|
+
|
22
|
+
if IS_PYDANTIC_V2:
|
23
|
+
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
24
|
+
else:
|
25
|
+
|
26
|
+
class Config:
|
27
|
+
frozen = True
|
28
|
+
smart_union = True
|
29
|
+
extra = pydantic.Extra.allow
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
2
|
+
|
3
|
+
from ..core.pydantic_utilities import UniversalBaseModel
|
4
|
+
import typing
|
5
|
+
from .vellum_document import VellumDocument
|
6
|
+
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
7
|
+
import pydantic
|
8
|
+
|
9
|
+
|
10
|
+
class DocumentVellumValue(UniversalBaseModel):
|
11
|
+
"""
|
12
|
+
A base Vellum primitive value representing a document.
|
13
|
+
"""
|
14
|
+
|
15
|
+
type: typing.Literal["DOCUMENT"] = "DOCUMENT"
|
16
|
+
value: typing.Optional[VellumDocument] = None
|
17
|
+
|
18
|
+
if IS_PYDANTIC_V2:
|
19
|
+
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
20
|
+
else:
|
21
|
+
|
22
|
+
class Config:
|
23
|
+
frozen = True
|
24
|
+
smart_union = True
|
25
|
+
extra = pydantic.Extra.allow
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
2
|
+
|
3
|
+
from ..core.pydantic_utilities import UniversalBaseModel
|
4
|
+
import typing
|
5
|
+
from .vellum_document_request import VellumDocumentRequest
|
6
|
+
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
7
|
+
import pydantic
|
8
|
+
|
9
|
+
|
10
|
+
class DocumentVellumValueRequest(UniversalBaseModel):
|
11
|
+
"""
|
12
|
+
A base Vellum primitive value representing a document.
|
13
|
+
"""
|
14
|
+
|
15
|
+
type: typing.Literal["DOCUMENT"] = "DOCUMENT"
|
16
|
+
value: typing.Optional[VellumDocumentRequest] = None
|
17
|
+
|
18
|
+
if IS_PYDANTIC_V2:
|
19
|
+
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
20
|
+
else:
|
21
|
+
|
22
|
+
class Config:
|
23
|
+
frozen = True
|
24
|
+
smart_union = True
|
25
|
+
extra = pydantic.Extra.allow
|
@@ -8,6 +8,7 @@ from .rich_text_prompt_block import RichTextPromptBlock
|
|
8
8
|
from .audio_prompt_block import AudioPromptBlock
|
9
9
|
from .function_call_prompt_block import FunctionCallPromptBlock
|
10
10
|
from .image_prompt_block import ImagePromptBlock
|
11
|
+
from .document_prompt_block import DocumentPromptBlock
|
11
12
|
import typing
|
12
13
|
|
13
14
|
if typing.TYPE_CHECKING:
|
@@ -20,4 +21,5 @@ PromptBlock = typing.Union[
|
|
20
21
|
AudioPromptBlock,
|
21
22
|
FunctionCallPromptBlock,
|
22
23
|
ImagePromptBlock,
|
24
|
+
DocumentPromptBlock,
|
23
25
|
]
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
2
|
+
|
3
|
+
from ..core.pydantic_utilities import UniversalBaseModel
|
4
|
+
import typing
|
5
|
+
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
6
|
+
import pydantic
|
7
|
+
|
8
|
+
|
9
|
+
class VellumDocument(UniversalBaseModel):
|
10
|
+
src: str
|
11
|
+
metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = None
|
12
|
+
|
13
|
+
if IS_PYDANTIC_V2:
|
14
|
+
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
15
|
+
else:
|
16
|
+
|
17
|
+
class Config:
|
18
|
+
frozen = True
|
19
|
+
smart_union = True
|
20
|
+
extra = pydantic.Extra.allow
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
2
|
+
|
3
|
+
from ..core.pydantic_utilities import UniversalBaseModel
|
4
|
+
import typing
|
5
|
+
from ..core.pydantic_utilities import IS_PYDANTIC_V2
|
6
|
+
import pydantic
|
7
|
+
|
8
|
+
|
9
|
+
class VellumDocumentRequest(UniversalBaseModel):
|
10
|
+
src: str
|
11
|
+
metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = None
|
12
|
+
|
13
|
+
if IS_PYDANTIC_V2:
|
14
|
+
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
15
|
+
else:
|
16
|
+
|
17
|
+
class Config:
|
18
|
+
frozen = True
|
19
|
+
smart_union = True
|
20
|
+
extra = pydantic.Extra.allow
|
@@ -7,6 +7,7 @@ from .number_vellum_value import NumberVellumValue
|
|
7
7
|
from .json_vellum_value import JsonVellumValue
|
8
8
|
from .image_vellum_value import ImageVellumValue
|
9
9
|
from .audio_vellum_value import AudioVellumValue
|
10
|
+
from .document_vellum_value import DocumentVellumValue
|
10
11
|
from .function_call_vellum_value import FunctionCallVellumValue
|
11
12
|
from .error_vellum_value import ErrorVellumValue
|
12
13
|
from .chat_history_vellum_value import ChatHistoryVellumValue
|
@@ -21,6 +22,7 @@ VellumValue = typing.Union[
|
|
21
22
|
JsonVellumValue,
|
22
23
|
ImageVellumValue,
|
23
24
|
AudioVellumValue,
|
25
|
+
DocumentVellumValue,
|
24
26
|
FunctionCallVellumValue,
|
25
27
|
ErrorVellumValue,
|
26
28
|
"ArrayVellumValue",
|
@@ -7,6 +7,7 @@ from .number_vellum_value_request import NumberVellumValueRequest
|
|
7
7
|
from .json_vellum_value_request import JsonVellumValueRequest
|
8
8
|
from .image_vellum_value_request import ImageVellumValueRequest
|
9
9
|
from .audio_vellum_value_request import AudioVellumValueRequest
|
10
|
+
from .document_vellum_value_request import DocumentVellumValueRequest
|
10
11
|
from .function_call_vellum_value_request import FunctionCallVellumValueRequest
|
11
12
|
from .error_vellum_value_request import ErrorVellumValueRequest
|
12
13
|
from .chat_history_vellum_value_request import ChatHistoryVellumValueRequest
|
@@ -21,6 +22,7 @@ VellumValueRequest = typing.Union[
|
|
21
22
|
JsonVellumValueRequest,
|
22
23
|
ImageVellumValueRequest,
|
23
24
|
AudioVellumValueRequest,
|
25
|
+
DocumentVellumValueRequest,
|
24
26
|
FunctionCallVellumValueRequest,
|
25
27
|
ErrorVellumValueRequest,
|
26
28
|
"ArrayVellumValueRequest",
|
vellum/workflows/exceptions.py
CHANGED
@@ -17,3 +17,21 @@ class NodeException(Exception):
|
|
17
17
|
@staticmethod
|
18
18
|
def of(workflow_error: WorkflowError) -> "NodeException":
|
19
19
|
return NodeException(message=workflow_error.message, code=workflow_error.code)
|
20
|
+
|
21
|
+
|
22
|
+
class WorkflowInitializationException(Exception):
|
23
|
+
def __init__(self, message: str, code: WorkflowErrorCode = WorkflowErrorCode.INVALID_INPUTS):
|
24
|
+
self.message = message
|
25
|
+
self.code = code
|
26
|
+
super().__init__(message)
|
27
|
+
|
28
|
+
@property
|
29
|
+
def error(self) -> WorkflowError:
|
30
|
+
return WorkflowError(
|
31
|
+
message=self.message,
|
32
|
+
code=self.code,
|
33
|
+
)
|
34
|
+
|
35
|
+
@staticmethod
|
36
|
+
def of(workflow_error: WorkflowError) -> "WorkflowInitializationException":
|
37
|
+
return WorkflowInitializationException(message=workflow_error.message, code=workflow_error.code)
|
vellum/workflows/inputs/base.py
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
from typing import Any, Iterator, Tuple, Type
|
1
|
+
from typing import Any, Iterator, Tuple, Type, Union, get_args, get_origin
|
2
2
|
from typing_extensions import dataclass_transform
|
3
3
|
|
4
4
|
from pydantic import GetCoreSchemaHandler
|
5
5
|
from pydantic_core import core_schema
|
6
6
|
|
7
|
+
from vellum.workflows.errors.types import WorkflowErrorCode
|
8
|
+
from vellum.workflows.exceptions import WorkflowInitializationException
|
7
9
|
from vellum.workflows.references import ExternalInputReference, WorkflowInputReference
|
8
10
|
from vellum.workflows.references.input import InputReference
|
9
11
|
from vellum.workflows.types.utils import get_class_attr_names, infer_types
|
@@ -40,7 +42,20 @@ class BaseInputs(metaclass=_BaseInputsMeta):
|
|
40
42
|
__parent_class__: Type = type(None)
|
41
43
|
|
42
44
|
def __init__(self, **kwargs: Any) -> None:
|
45
|
+
for name, field_type in self.__class__.__annotations__.items():
|
46
|
+
if name not in kwargs and name not in vars(self.__class__):
|
47
|
+
origin = get_origin(field_type)
|
48
|
+
args = get_args(field_type)
|
49
|
+
if not (origin is Union and type(None) in args):
|
50
|
+
raise WorkflowInitializationException(
|
51
|
+
message="Required input variables should have defined value",
|
52
|
+
code=WorkflowErrorCode.INVALID_INPUTS,
|
53
|
+
)
|
54
|
+
|
43
55
|
for name, value in kwargs.items():
|
56
|
+
field_type = self.__class__.__annotations__.get(name)
|
57
|
+
if field_type:
|
58
|
+
self._validate_input(value, field_type)
|
44
59
|
setattr(self, name, value)
|
45
60
|
|
46
61
|
def __iter__(self) -> Iterator[Tuple[InputReference, Any]]:
|
@@ -48,6 +63,17 @@ class BaseInputs(metaclass=_BaseInputsMeta):
|
|
48
63
|
if hasattr(self, input_descriptor.name):
|
49
64
|
yield (input_descriptor, getattr(self, input_descriptor.name))
|
50
65
|
|
66
|
+
def _validate_input(self, value: Any, field_type: Any) -> None:
|
67
|
+
if value is None:
|
68
|
+
# Check if field_type is Optional
|
69
|
+
origin = get_origin(field_type)
|
70
|
+
args = get_args(field_type)
|
71
|
+
if not (origin is Union and type(None) in args):
|
72
|
+
raise WorkflowInitializationException(
|
73
|
+
message="Required input variables should have defined value",
|
74
|
+
code=WorkflowErrorCode.INVALID_INPUTS,
|
75
|
+
)
|
76
|
+
|
51
77
|
@classmethod
|
52
78
|
def __get_pydantic_core_schema__(
|
53
79
|
cls, source_type: Type[Any], handler: GetCoreSchemaHandler
|
File without changes
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import pytest
|
2
|
+
from typing import Optional
|
3
|
+
|
4
|
+
from vellum.workflows.errors import WorkflowErrorCode
|
5
|
+
from vellum.workflows.exceptions import WorkflowInitializationException
|
6
|
+
from vellum.workflows.inputs import BaseInputs
|
7
|
+
|
8
|
+
|
9
|
+
def test_base_inputs_happy_path():
|
10
|
+
# GIVEN some input class with required and optional fields
|
11
|
+
class TestInputs(BaseInputs):
|
12
|
+
required_string: str
|
13
|
+
required_int: int
|
14
|
+
optional_string: Optional[str]
|
15
|
+
|
16
|
+
# WHEN we assign the inputs some valid values
|
17
|
+
inputs = TestInputs(required_string="hello", required_int=42, optional_string=None)
|
18
|
+
|
19
|
+
# THEN the inputs should have the correct values
|
20
|
+
assert inputs.required_string == "hello"
|
21
|
+
assert inputs.required_int == 42
|
22
|
+
assert inputs.optional_string is None
|
23
|
+
|
24
|
+
|
25
|
+
def test_base_inputs_empty_value():
|
26
|
+
# GIVEN some input class with required and optional string fields
|
27
|
+
class TestInputs(BaseInputs):
|
28
|
+
required_string: str
|
29
|
+
optional_string: Optional[str]
|
30
|
+
|
31
|
+
# WHEN we try to omit a required field
|
32
|
+
with pytest.raises(WorkflowInitializationException) as exc_info:
|
33
|
+
TestInputs(optional_string="ok") # type: ignore
|
34
|
+
|
35
|
+
# THEN it should raise a NodeException with the correct error message and code
|
36
|
+
assert exc_info.value.code == WorkflowErrorCode.INVALID_INPUTS
|
37
|
+
assert "Required input variables should have defined value" in str(exc_info.value)
|
38
|
+
|
39
|
+
|
40
|
+
def test_base_inputs_with_default():
|
41
|
+
# GIVEN some input class with a field that has a default value
|
42
|
+
class TestInputs(BaseInputs):
|
43
|
+
string_with_default: str = "default_value"
|
44
|
+
|
45
|
+
# WHEN we create an instance without providing the field
|
46
|
+
inputs = TestInputs()
|
47
|
+
|
48
|
+
# THEN it should use the default value
|
49
|
+
assert inputs.string_with_default == "default_value"
|
@@ -70,7 +70,7 @@ class InlineSubworkflowNode(
|
|
70
70
|
subworkflow_inputs: ClassVar[Union[EntityInputsInterface, BaseInputs, Type[undefined]]] = undefined
|
71
71
|
|
72
72
|
def run(self) -> Iterator[BaseOutput]:
|
73
|
-
with execution_context(parent_context=get_parent_context()
|
73
|
+
with execution_context(parent_context=get_parent_context()):
|
74
74
|
subworkflow = self.subworkflow(
|
75
75
|
parent_state=self.state,
|
76
76
|
context=WorkflowContext(vellum_client=self._context.vellum_client),
|
@@ -16,10 +16,9 @@ from typing import (
|
|
16
16
|
overload,
|
17
17
|
)
|
18
18
|
|
19
|
-
from vellum.workflows.context import execution_context,
|
19
|
+
from vellum.workflows.context import ExecutionContext, execution_context, get_execution_context
|
20
20
|
from vellum.workflows.descriptors.base import BaseDescriptor
|
21
21
|
from vellum.workflows.errors.types import WorkflowErrorCode
|
22
|
-
from vellum.workflows.events.types import ParentContext
|
23
22
|
from vellum.workflows.exceptions import NodeException
|
24
23
|
from vellum.workflows.inputs.base import BaseInputs
|
25
24
|
from vellum.workflows.nodes.bases.base_adornment_node import BaseAdornmentNode
|
@@ -76,13 +75,13 @@ class MapNode(BaseAdornmentNode[StateType], Generic[StateType, MapNodeItemType])
|
|
76
75
|
fulfilled_iterations: List[bool] = []
|
77
76
|
for index, item in enumerate(self.items):
|
78
77
|
fulfilled_iterations.append(False)
|
79
|
-
|
78
|
+
current_execution_context = get_execution_context()
|
80
79
|
thread = Thread(
|
81
80
|
target=self._context_run_subworkflow,
|
82
81
|
kwargs={
|
83
82
|
"item": item,
|
84
83
|
"index": index,
|
85
|
-
"
|
84
|
+
"current_execution_context": current_execution_context,
|
86
85
|
},
|
87
86
|
)
|
88
87
|
if self.max_concurrency is None:
|
@@ -143,10 +142,11 @@ class MapNode(BaseAdornmentNode[StateType], Generic[StateType, MapNodeItemType])
|
|
143
142
|
yield BaseOutput(name=output_name, value=output_list)
|
144
143
|
|
145
144
|
def _context_run_subworkflow(
|
146
|
-
self, *, item: MapNodeItemType, index: int,
|
145
|
+
self, *, item: MapNodeItemType, index: int, current_execution_context: ExecutionContext
|
147
146
|
) -> None:
|
148
|
-
parent_context =
|
149
|
-
|
147
|
+
parent_context = current_execution_context.parent_context
|
148
|
+
trace_id = current_execution_context.trace_id
|
149
|
+
with execution_context(parent_context=parent_context, trace_id=trace_id):
|
150
150
|
self._run_subworkflow(item=item, index=index)
|
151
151
|
|
152
152
|
def _run_subworkflow(self, *, item: MapNodeItemType, index: int) -> None:
|
@@ -27,7 +27,7 @@ class TryNode(BaseAdornmentNode[StateType], Generic[StateType]):
|
|
27
27
|
error: Optional[WorkflowError] = None
|
28
28
|
|
29
29
|
def run(self) -> Iterator[BaseOutput]:
|
30
|
-
parent_context = get_parent_context()
|
30
|
+
parent_context = get_parent_context()
|
31
31
|
with execution_context(parent_context=parent_context):
|
32
32
|
subworkflow = self.subworkflow(
|
33
33
|
parent_state=self.state,
|