vellum-ai 0.12.14__py3-none-any.whl → 0.12.16__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 +6 -0
- vellum/client/__init__.py +2 -6
- vellum/client/core/client_wrapper.py +1 -1
- vellum/client/environment.py +3 -3
- vellum/client/resources/ad_hoc/client.py +2 -6
- vellum/client/resources/container_images/client.py +0 -8
- vellum/client/resources/metric_definitions/client.py +2 -6
- vellum/client/resources/workflows/client.py +8 -8
- vellum/client/types/__init__.py +6 -0
- vellum/client/types/audio_prompt_block.py +29 -0
- vellum/client/types/function_call_prompt_block.py +30 -0
- vellum/client/types/image_prompt_block.py +29 -0
- vellum/client/types/prompt_block.py +12 -1
- vellum/client/types/workflow_push_response.py +1 -0
- vellum/prompts/blocks/compilation.py +43 -0
- vellum/types/audio_prompt_block.py +3 -0
- vellum/types/function_call_prompt_block.py +3 -0
- vellum/types/image_prompt_block.py +3 -0
- vellum/workflows/nodes/core/inline_subworkflow_node/node.py +10 -2
- vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py +16 -0
- {vellum_ai-0.12.14.dist-info → vellum_ai-0.12.16.dist-info}/METADATA +11 -9
- {vellum_ai-0.12.14.dist-info → vellum_ai-0.12.16.dist-info}/RECORD +59 -48
- vellum_cli/__init__.py +14 -0
- vellum_cli/config.py +4 -0
- vellum_cli/pull.py +20 -5
- vellum_cli/push.py +33 -4
- vellum_cli/tests/test_pull.py +19 -1
- vellum_cli/tests/test_push.py +63 -0
- vellum_ee/workflows/display/nodes/vellum/__init__.py +2 -0
- vellum_ee/workflows/display/nodes/vellum/api_node.py +3 -3
- vellum_ee/workflows/display/nodes/vellum/base_node.py +35 -0
- vellum_ee/workflows/display/nodes/vellum/code_execution_node.py +2 -2
- vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +2 -2
- vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py +20 -6
- vellum_ee/workflows/display/nodes/vellum/map_node.py +1 -0
- vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +2 -2
- vellum_ee/workflows/display/nodes/vellum/search_node.py +4 -2
- vellum_ee/workflows/display/nodes/vellum/templating_node.py +1 -1
- vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +3 -3
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/__init__.py +0 -0
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py +28 -0
- vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_trigger_serialization.py +123 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +6 -46
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_error_node_serialization.py +3 -25
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_generic_node_serialization.py +168 -0
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +18 -10
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +18 -10
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +3 -25
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py +2 -8
- vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py +13 -27
- vellum_ee/workflows/display/types.py +5 -1
- vellum_ee/workflows/display/utils/vellum.py +3 -3
- vellum_ee/workflows/display/vellum.py +4 -0
- vellum_ee/workflows/display/workflows/base_workflow_display.py +44 -16
- vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py +3 -0
- vellum_ee/workflows/display/workflows/vellum_workflow_display.py +7 -8
- {vellum_ai-0.12.14.dist-info → vellum_ai-0.12.16.dist-info}/LICENSE +0 -0
- {vellum_ai-0.12.14.dist-info → vellum_ai-0.12.16.dist-info}/WHEEL +0 -0
- {vellum_ai-0.12.14.dist-info → vellum_ai-0.12.16.dist-info}/entry_points.txt +0 -0
    
        vellum/__init__.py
    CHANGED
    
    | @@ -24,6 +24,7 @@ from .types import ( | |
| 24 24 | 
             
                ArrayVellumValueRequest,
         | 
| 25 25 | 
             
                AudioChatMessageContent,
         | 
| 26 26 | 
             
                AudioChatMessageContentRequest,
         | 
| 27 | 
            +
                AudioPromptBlock,
         | 
| 27 28 | 
             
                AudioVariableValue,
         | 
| 28 29 | 
             
                AudioVellumValue,
         | 
| 29 30 | 
             
                AudioVellumValueRequest,
         | 
| @@ -134,6 +135,7 @@ from .types import ( | |
| 134 135 | 
             
                FunctionCallChatMessageContentValue,
         | 
| 135 136 | 
             
                FunctionCallChatMessageContentValueRequest,
         | 
| 136 137 | 
             
                FunctionCallInput,
         | 
| 138 | 
            +
                FunctionCallPromptBlock,
         | 
| 137 139 | 
             
                FunctionCallRequest,
         | 
| 138 140 | 
             
                FunctionCallVariableValue,
         | 
| 139 141 | 
             
                FunctionCallVellumValue,
         | 
| @@ -158,6 +160,7 @@ from .types import ( | |
| 158 160 | 
             
                HkunlpInstructorXlVectorizerRequest,
         | 
| 159 161 | 
             
                ImageChatMessageContent,
         | 
| 160 162 | 
             
                ImageChatMessageContentRequest,
         | 
| 163 | 
            +
                ImagePromptBlock,
         | 
| 161 164 | 
             
                ImageVariableValue,
         | 
| 162 165 | 
             
                ImageVellumValue,
         | 
| 163 166 | 
             
                ImageVellumValueRequest,
         | 
| @@ -548,6 +551,7 @@ __all__ = [ | |
| 548 551 | 
             
                "AsyncVellum",
         | 
| 549 552 | 
             
                "AudioChatMessageContent",
         | 
| 550 553 | 
             
                "AudioChatMessageContentRequest",
         | 
| 554 | 
            +
                "AudioPromptBlock",
         | 
| 551 555 | 
             
                "AudioVariableValue",
         | 
| 552 556 | 
             
                "AudioVellumValue",
         | 
| 553 557 | 
             
                "AudioVellumValueRequest",
         | 
| @@ -663,6 +667,7 @@ __all__ = [ | |
| 663 667 | 
             
                "FunctionCallChatMessageContentValue",
         | 
| 664 668 | 
             
                "FunctionCallChatMessageContentValueRequest",
         | 
| 665 669 | 
             
                "FunctionCallInput",
         | 
| 670 | 
            +
                "FunctionCallPromptBlock",
         | 
| 666 671 | 
             
                "FunctionCallRequest",
         | 
| 667 672 | 
             
                "FunctionCallVariableValue",
         | 
| 668 673 | 
             
                "FunctionCallVellumValue",
         | 
| @@ -687,6 +692,7 @@ __all__ = [ | |
| 687 692 | 
             
                "HkunlpInstructorXlVectorizerRequest",
         | 
| 688 693 | 
             
                "ImageChatMessageContent",
         | 
| 689 694 | 
             
                "ImageChatMessageContentRequest",
         | 
| 695 | 
            +
                "ImagePromptBlock",
         | 
| 690 696 | 
             
                "ImageVariableValue",
         | 
| 691 697 | 
             
                "ImageVellumValue",
         | 
| 692 698 | 
             
                "ImageVellumValueRequest",
         | 
    
        vellum/client/__init__.py
    CHANGED
    
    | @@ -154,8 +154,6 @@ class Vellum: | |
| 154 154 | 
             
                    request_options: typing.Optional[RequestOptions] = None,
         | 
| 155 155 | 
             
                ) -> CodeExecutorResponse:
         | 
| 156 156 | 
             
                    """
         | 
| 157 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 158 | 
            -
             | 
| 159 157 | 
             
                    Parameters
         | 
| 160 158 | 
             
                    ----------
         | 
| 161 159 | 
             
                    code : str
         | 
| @@ -203,7 +201,7 @@ class Vellum: | |
| 203 201 | 
             
                    """
         | 
| 204 202 | 
             
                    _response = self._client_wrapper.httpx_client.request(
         | 
| 205 203 | 
             
                        "v1/execute-code",
         | 
| 206 | 
            -
                        base_url=self._client_wrapper.get_environment(). | 
| 204 | 
            +
                        base_url=self._client_wrapper.get_environment().predict,
         | 
| 207 205 | 
             
                        method="POST",
         | 
| 208 206 | 
             
                        json={
         | 
| 209 207 | 
             
                            "code": code,
         | 
| @@ -1419,8 +1417,6 @@ class AsyncVellum: | |
| 1419 1417 | 
             
                    request_options: typing.Optional[RequestOptions] = None,
         | 
| 1420 1418 | 
             
                ) -> CodeExecutorResponse:
         | 
| 1421 1419 | 
             
                    """
         | 
| 1422 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 1423 | 
            -
             | 
| 1424 1420 | 
             
                    Parameters
         | 
| 1425 1421 | 
             
                    ----------
         | 
| 1426 1422 | 
             
                    code : str
         | 
| @@ -1476,7 +1472,7 @@ class AsyncVellum: | |
| 1476 1472 | 
             
                    """
         | 
| 1477 1473 | 
             
                    _response = await self._client_wrapper.httpx_client.request(
         | 
| 1478 1474 | 
             
                        "v1/execute-code",
         | 
| 1479 | 
            -
                        base_url=self._client_wrapper.get_environment(). | 
| 1475 | 
            +
                        base_url=self._client_wrapper.get_environment().predict,
         | 
| 1480 1476 | 
             
                        method="POST",
         | 
| 1481 1477 | 
             
                        json={
         | 
| 1482 1478 | 
             
                            "code": code,
         | 
| @@ -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.12. | 
| 21 | 
            +
                        "X-Fern-SDK-Version": "0.12.16",
         | 
| 22 22 | 
             
                    }
         | 
| 23 23 | 
             
                    headers["X_API_KEY"] = self.api_key
         | 
| 24 24 | 
             
                    return headers
         | 
    
        vellum/client/environment.py
    CHANGED
    
    | @@ -6,12 +6,12 @@ from __future__ import annotations | |
| 6 6 | 
             
            class VellumEnvironment:
         | 
| 7 7 | 
             
                PRODUCTION: VellumEnvironment
         | 
| 8 8 |  | 
| 9 | 
            -
                def __init__(self, *, default: str,  | 
| 9 | 
            +
                def __init__(self, *, default: str, predict: str, documents: str):
         | 
| 10 10 | 
             
                    self.default = default
         | 
| 11 | 
            -
                    self.documents = documents
         | 
| 12 11 | 
             
                    self.predict = predict
         | 
| 12 | 
            +
                    self.documents = documents
         | 
| 13 13 |  | 
| 14 14 |  | 
| 15 15 | 
             
            VellumEnvironment.PRODUCTION = VellumEnvironment(
         | 
| 16 | 
            -
                default="https://api.vellum.ai",  | 
| 16 | 
            +
                default="https://api.vellum.ai", predict="https://predict.vellum.ai", documents="https://documents.vellum.ai"
         | 
| 17 17 | 
             
            )
         | 
| @@ -43,8 +43,6 @@ class AdHocClient: | |
| 43 43 | 
             
                    request_options: typing.Optional[RequestOptions] = None,
         | 
| 44 44 | 
             
                ) -> typing.Iterator[AdHocExecutePromptEvent]:
         | 
| 45 45 | 
             
                    """
         | 
| 46 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 47 | 
            -
             | 
| 48 46 | 
             
                    Parameters
         | 
| 49 47 | 
             
                    ----------
         | 
| 50 48 | 
             
                    ml_model : str
         | 
| @@ -111,7 +109,7 @@ class AdHocClient: | |
| 111 109 | 
             
                    """
         | 
| 112 110 | 
             
                    with self._client_wrapper.httpx_client.stream(
         | 
| 113 111 | 
             
                        "v1/ad-hoc/execute-prompt-stream",
         | 
| 114 | 
            -
                        base_url=self._client_wrapper.get_environment(). | 
| 112 | 
            +
                        base_url=self._client_wrapper.get_environment().predict,
         | 
| 115 113 | 
             
                        method="POST",
         | 
| 116 114 | 
             
                        json={
         | 
| 117 115 | 
             
                            "ml_model": ml_model,
         | 
| @@ -211,8 +209,6 @@ class AsyncAdHocClient: | |
| 211 209 | 
             
                    request_options: typing.Optional[RequestOptions] = None,
         | 
| 212 210 | 
             
                ) -> typing.AsyncIterator[AdHocExecutePromptEvent]:
         | 
| 213 211 | 
             
                    """
         | 
| 214 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 215 | 
            -
             | 
| 216 212 | 
             
                    Parameters
         | 
| 217 213 | 
             
                    ----------
         | 
| 218 214 | 
             
                    ml_model : str
         | 
| @@ -287,7 +283,7 @@ class AsyncAdHocClient: | |
| 287 283 | 
             
                    """
         | 
| 288 284 | 
             
                    async with self._client_wrapper.httpx_client.stream(
         | 
| 289 285 | 
             
                        "v1/ad-hoc/execute-prompt-stream",
         | 
| 290 | 
            -
                        base_url=self._client_wrapper.get_environment(). | 
| 286 | 
            +
                        base_url=self._client_wrapper.get_environment().predict,
         | 
| 291 287 | 
             
                        method="POST",
         | 
| 292 288 | 
             
                        json={
         | 
| 293 289 | 
             
                            "ml_model": ml_model,
         | 
| @@ -134,8 +134,6 @@ class ContainerImagesClient: | |
| 134 134 |  | 
| 135 135 | 
             
                def docker_service_token(self, *, request_options: typing.Optional[RequestOptions] = None) -> DockerServiceToken:
         | 
| 136 136 | 
             
                    """
         | 
| 137 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 138 | 
            -
             | 
| 139 137 | 
             
                    Parameters
         | 
| 140 138 | 
             
                    ----------
         | 
| 141 139 | 
             
                    request_options : typing.Optional[RequestOptions]
         | 
| @@ -184,8 +182,6 @@ class ContainerImagesClient: | |
| 184 182 | 
             
                    request_options: typing.Optional[RequestOptions] = None,
         | 
| 185 183 | 
             
                ) -> ContainerImageRead:
         | 
| 186 184 | 
             
                    """
         | 
| 187 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 188 | 
            -
             | 
| 189 185 | 
             
                    Parameters
         | 
| 190 186 | 
             
                    ----------
         | 
| 191 187 | 
             
                    name : str
         | 
| @@ -378,8 +374,6 @@ class AsyncContainerImagesClient: | |
| 378 374 | 
             
                    self, *, request_options: typing.Optional[RequestOptions] = None
         | 
| 379 375 | 
             
                ) -> DockerServiceToken:
         | 
| 380 376 | 
             
                    """
         | 
| 381 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 382 | 
            -
             | 
| 383 377 | 
             
                    Parameters
         | 
| 384 378 | 
             
                    ----------
         | 
| 385 379 | 
             
                    request_options : typing.Optional[RequestOptions]
         | 
| @@ -436,8 +430,6 @@ class AsyncContainerImagesClient: | |
| 436 430 | 
             
                    request_options: typing.Optional[RequestOptions] = None,
         | 
| 437 431 | 
             
                ) -> ContainerImageRead:
         | 
| 438 432 | 
             
                    """
         | 
| 439 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 440 | 
            -
             | 
| 441 433 | 
             
                    Parameters
         | 
| 442 434 | 
             
                    ----------
         | 
| 443 435 | 
             
                    name : str
         | 
| @@ -30,8 +30,6 @@ class MetricDefinitionsClient: | |
| 30 30 | 
             
                    request_options: typing.Optional[RequestOptions] = None,
         | 
| 31 31 | 
             
                ) -> MetricDefinitionExecution:
         | 
| 32 32 | 
             
                    """
         | 
| 33 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 34 | 
            -
             | 
| 35 33 | 
             
                    Parameters
         | 
| 36 34 | 
             
                    ----------
         | 
| 37 35 | 
             
                    id : str
         | 
| @@ -68,7 +66,7 @@ class MetricDefinitionsClient: | |
| 68 66 | 
             
                    """
         | 
| 69 67 | 
             
                    _response = self._client_wrapper.httpx_client.request(
         | 
| 70 68 | 
             
                        f"v1/metric-definitions/{jsonable_encoder(id)}/execute",
         | 
| 71 | 
            -
                        base_url=self._client_wrapper.get_environment(). | 
| 69 | 
            +
                        base_url=self._client_wrapper.get_environment().predict,
         | 
| 72 70 | 
             
                        method="POST",
         | 
| 73 71 | 
             
                        json={
         | 
| 74 72 | 
             
                            "inputs": convert_and_respect_annotation_metadata(
         | 
| @@ -159,8 +157,6 @@ class AsyncMetricDefinitionsClient: | |
| 159 157 | 
             
                    request_options: typing.Optional[RequestOptions] = None,
         | 
| 160 158 | 
             
                ) -> MetricDefinitionExecution:
         | 
| 161 159 | 
             
                    """
         | 
| 162 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 163 | 
            -
             | 
| 164 160 | 
             
                    Parameters
         | 
| 165 161 | 
             
                    ----------
         | 
| 166 162 | 
             
                    id : str
         | 
| @@ -205,7 +201,7 @@ class AsyncMetricDefinitionsClient: | |
| 205 201 | 
             
                    """
         | 
| 206 202 | 
             
                    _response = await self._client_wrapper.httpx_client.request(
         | 
| 207 203 | 
             
                        f"v1/metric-definitions/{jsonable_encoder(id)}/execute",
         | 
| 208 | 
            -
                        base_url=self._client_wrapper.get_environment(). | 
| 204 | 
            +
                        base_url=self._client_wrapper.get_environment().predict,
         | 
| 209 205 | 
             
                        method="POST",
         | 
| 210 206 | 
             
                        json={
         | 
| 211 207 | 
             
                            "inputs": convert_and_respect_annotation_metadata(
         | 
| @@ -35,8 +35,6 @@ class WorkflowsClient: | |
| 35 35 | 
             
                    request_options: typing.Optional[RequestOptions] = None,
         | 
| 36 36 | 
             
                ) -> typing.Iterator[bytes]:
         | 
| 37 37 | 
             
                    """
         | 
| 38 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 39 | 
            -
             | 
| 40 38 | 
             
                    Parameters
         | 
| 41 39 | 
             
                    ----------
         | 
| 42 40 | 
             
                    id : str
         | 
| @@ -102,11 +100,10 @@ class WorkflowsClient: | |
| 102 100 | 
             
                    workflow_sandbox_id: typing.Optional[str] = OMIT,
         | 
| 103 101 | 
             
                    deployment_config: typing.Optional[WorkflowPushDeploymentConfigRequest] = OMIT,
         | 
| 104 102 | 
             
                    artifact: typing.Optional[core.File] = OMIT,
         | 
| 103 | 
            +
                    dry_run: typing.Optional[bool] = OMIT,
         | 
| 105 104 | 
             
                    request_options: typing.Optional[RequestOptions] = None,
         | 
| 106 105 | 
             
                ) -> WorkflowPushResponse:
         | 
| 107 106 | 
             
                    """
         | 
| 108 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 109 | 
            -
             | 
| 110 107 | 
             
                    Parameters
         | 
| 111 108 | 
             
                    ----------
         | 
| 112 109 | 
             
                    exec_config : WorkflowPushExecConfig
         | 
| @@ -121,6 +118,8 @@ class WorkflowsClient: | |
| 121 118 | 
             
                    artifact : typing.Optional[core.File]
         | 
| 122 119 | 
             
                        See core.File for more documentation
         | 
| 123 120 |  | 
| 121 | 
            +
                    dry_run : typing.Optional[bool]
         | 
| 122 | 
            +
             | 
| 124 123 | 
             
                    request_options : typing.Optional[RequestOptions]
         | 
| 125 124 | 
             
                        Request-specific configuration.
         | 
| 126 125 |  | 
| @@ -150,6 +149,7 @@ class WorkflowsClient: | |
| 150 149 | 
             
                            "label": label,
         | 
| 151 150 | 
             
                            "workflow_sandbox_id": workflow_sandbox_id,
         | 
| 152 151 | 
             
                            "deployment_config": deployment_config,
         | 
| 152 | 
            +
                            "dry_run": dry_run,
         | 
| 153 153 | 
             
                        },
         | 
| 154 154 | 
             
                        files={
         | 
| 155 155 | 
             
                            "artifact": artifact,
         | 
| @@ -188,8 +188,6 @@ class AsyncWorkflowsClient: | |
| 188 188 | 
             
                    request_options: typing.Optional[RequestOptions] = None,
         | 
| 189 189 | 
             
                ) -> typing.AsyncIterator[bytes]:
         | 
| 190 190 | 
             
                    """
         | 
| 191 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 192 | 
            -
             | 
| 193 191 | 
             
                    Parameters
         | 
| 194 192 | 
             
                    ----------
         | 
| 195 193 | 
             
                    id : str
         | 
| @@ -255,11 +253,10 @@ class AsyncWorkflowsClient: | |
| 255 253 | 
             
                    workflow_sandbox_id: typing.Optional[str] = OMIT,
         | 
| 256 254 | 
             
                    deployment_config: typing.Optional[WorkflowPushDeploymentConfigRequest] = OMIT,
         | 
| 257 255 | 
             
                    artifact: typing.Optional[core.File] = OMIT,
         | 
| 256 | 
            +
                    dry_run: typing.Optional[bool] = OMIT,
         | 
| 258 257 | 
             
                    request_options: typing.Optional[RequestOptions] = None,
         | 
| 259 258 | 
             
                ) -> WorkflowPushResponse:
         | 
| 260 259 | 
             
                    """
         | 
| 261 | 
            -
                    An internal-only endpoint that's subject to breaking changes without notice. Not intended for public use.
         | 
| 262 | 
            -
             | 
| 263 260 | 
             
                    Parameters
         | 
| 264 261 | 
             
                    ----------
         | 
| 265 262 | 
             
                    exec_config : WorkflowPushExecConfig
         | 
| @@ -274,6 +271,8 @@ class AsyncWorkflowsClient: | |
| 274 271 | 
             
                    artifact : typing.Optional[core.File]
         | 
| 275 272 | 
             
                        See core.File for more documentation
         | 
| 276 273 |  | 
| 274 | 
            +
                    dry_run : typing.Optional[bool]
         | 
| 275 | 
            +
             | 
| 277 276 | 
             
                    request_options : typing.Optional[RequestOptions]
         | 
| 278 277 | 
             
                        Request-specific configuration.
         | 
| 279 278 |  | 
| @@ -311,6 +310,7 @@ class AsyncWorkflowsClient: | |
| 311 310 | 
             
                            "label": label,
         | 
| 312 311 | 
             
                            "workflow_sandbox_id": workflow_sandbox_id,
         | 
| 313 312 | 
             
                            "deployment_config": deployment_config,
         | 
| 313 | 
            +
                            "dry_run": dry_run,
         | 
| 314 314 | 
             
                        },
         | 
| 315 315 | 
             
                        files={
         | 
| 316 316 | 
             
                            "artifact": artifact,
         | 
    
        vellum/client/types/__init__.py
    CHANGED
    
    | @@ -20,6 +20,7 @@ from .array_vellum_value import ArrayVellumValue | |
| 20 20 | 
             
            from .array_vellum_value_request import ArrayVellumValueRequest
         | 
| 21 21 | 
             
            from .audio_chat_message_content import AudioChatMessageContent
         | 
| 22 22 | 
             
            from .audio_chat_message_content_request import AudioChatMessageContentRequest
         | 
| 23 | 
            +
            from .audio_prompt_block import AudioPromptBlock
         | 
| 23 24 | 
             
            from .audio_variable_value import AudioVariableValue
         | 
| 24 25 | 
             
            from .audio_vellum_value import AudioVellumValue
         | 
| 25 26 | 
             
            from .audio_vellum_value_request import AudioVellumValueRequest
         | 
| @@ -138,6 +139,7 @@ from .function_call_chat_message_content_request import FunctionCallChatMessageC | |
| 138 139 | 
             
            from .function_call_chat_message_content_value import FunctionCallChatMessageContentValue
         | 
| 139 140 | 
             
            from .function_call_chat_message_content_value_request import FunctionCallChatMessageContentValueRequest
         | 
| 140 141 | 
             
            from .function_call_input import FunctionCallInput
         | 
| 142 | 
            +
            from .function_call_prompt_block import FunctionCallPromptBlock
         | 
| 141 143 | 
             
            from .function_call_request import FunctionCallRequest
         | 
| 142 144 | 
             
            from .function_call_variable_value import FunctionCallVariableValue
         | 
| 143 145 | 
             
            from .function_call_vellum_value import FunctionCallVellumValue
         | 
| @@ -166,6 +168,7 @@ from .hkunlp_instructor_xl_vectorizer import HkunlpInstructorXlVectorizer | |
| 166 168 | 
             
            from .hkunlp_instructor_xl_vectorizer_request import HkunlpInstructorXlVectorizerRequest
         | 
| 167 169 | 
             
            from .image_chat_message_content import ImageChatMessageContent
         | 
| 168 170 | 
             
            from .image_chat_message_content_request import ImageChatMessageContentRequest
         | 
| 171 | 
            +
            from .image_prompt_block import ImagePromptBlock
         | 
| 169 172 | 
             
            from .image_variable_value import ImageVariableValue
         | 
| 170 173 | 
             
            from .image_vellum_value import ImageVellumValue
         | 
| 171 174 | 
             
            from .image_vellum_value_request import ImageVellumValueRequest
         | 
| @@ -542,6 +545,7 @@ __all__ = [ | |
| 542 545 | 
             
                "ArrayVellumValueRequest",
         | 
| 543 546 | 
             
                "AudioChatMessageContent",
         | 
| 544 547 | 
             
                "AudioChatMessageContentRequest",
         | 
| 548 | 
            +
                "AudioPromptBlock",
         | 
| 545 549 | 
             
                "AudioVariableValue",
         | 
| 546 550 | 
             
                "AudioVellumValue",
         | 
| 547 551 | 
             
                "AudioVellumValueRequest",
         | 
| @@ -652,6 +656,7 @@ __all__ = [ | |
| 652 656 | 
             
                "FunctionCallChatMessageContentValue",
         | 
| 653 657 | 
             
                "FunctionCallChatMessageContentValueRequest",
         | 
| 654 658 | 
             
                "FunctionCallInput",
         | 
| 659 | 
            +
                "FunctionCallPromptBlock",
         | 
| 655 660 | 
             
                "FunctionCallRequest",
         | 
| 656 661 | 
             
                "FunctionCallVariableValue",
         | 
| 657 662 | 
             
                "FunctionCallVellumValue",
         | 
| @@ -676,6 +681,7 @@ __all__ = [ | |
| 676 681 | 
             
                "HkunlpInstructorXlVectorizerRequest",
         | 
| 677 682 | 
             
                "ImageChatMessageContent",
         | 
| 678 683 | 
             
                "ImageChatMessageContentRequest",
         | 
| 684 | 
            +
                "ImagePromptBlock",
         | 
| 679 685 | 
             
                "ImageVariableValue",
         | 
| 680 686 | 
             
                "ImageVellumValue",
         | 
| 681 687 | 
             
                "ImageVellumValueRequest",
         | 
| @@ -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 AudioPromptBlock(UniversalBaseModel):
         | 
| 12 | 
            +
                """
         | 
| 13 | 
            +
                A block that represents an audio file in a prompt template.
         | 
| 14 | 
            +
                """
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                block_type: typing.Literal["AUDIO"] = "AUDIO"
         | 
| 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,30 @@ | |
| 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 FunctionCallPromptBlock(UniversalBaseModel):
         | 
| 12 | 
            +
                """
         | 
| 13 | 
            +
                A block that represents a function call in a prompt template.
         | 
| 14 | 
            +
                """
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                block_type: typing.Literal["FUNCTION_CALL"] = "FUNCTION_CALL"
         | 
| 17 | 
            +
                state: typing.Optional[PromptBlockState] = None
         | 
| 18 | 
            +
                cache_config: typing.Optional[EphemeralPromptCacheConfig] = None
         | 
| 19 | 
            +
                id: typing.Optional[str] = None
         | 
| 20 | 
            +
                name: str
         | 
| 21 | 
            +
                arguments: typing.Dict[str, typing.Optional[typing.Any]]
         | 
| 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
         | 
| @@ -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 ImagePromptBlock(UniversalBaseModel):
         | 
| 12 | 
            +
                """
         | 
| 13 | 
            +
                A block that represents an image in a prompt template.
         | 
| 14 | 
            +
                """
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                block_type: typing.Literal["IMAGE"] = "IMAGE"
         | 
| 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
         | 
| @@ -5,8 +5,19 @@ import typing | |
| 5 5 | 
             
            from .jinja_prompt_block import JinjaPromptBlock
         | 
| 6 6 | 
             
            from .variable_prompt_block import VariablePromptBlock
         | 
| 7 7 | 
             
            from .rich_text_prompt_block import RichTextPromptBlock
         | 
| 8 | 
            +
            from .audio_prompt_block import AudioPromptBlock
         | 
| 9 | 
            +
            from .function_call_prompt_block import FunctionCallPromptBlock
         | 
| 10 | 
            +
            from .image_prompt_block import ImagePromptBlock
         | 
| 8 11 | 
             
            import typing
         | 
| 9 12 |  | 
| 10 13 | 
             
            if typing.TYPE_CHECKING:
         | 
| 11 14 | 
             
                from .chat_message_prompt_block import ChatMessagePromptBlock
         | 
| 12 | 
            -
            PromptBlock = typing.Union[ | 
| 15 | 
            +
            PromptBlock = typing.Union[
         | 
| 16 | 
            +
                JinjaPromptBlock,
         | 
| 17 | 
            +
                "ChatMessagePromptBlock",
         | 
| 18 | 
            +
                VariablePromptBlock,
         | 
| 19 | 
            +
                RichTextPromptBlock,
         | 
| 20 | 
            +
                AudioPromptBlock,
         | 
| 21 | 
            +
                FunctionCallPromptBlock,
         | 
| 22 | 
            +
                ImagePromptBlock,
         | 
| 23 | 
            +
            ]
         | 
| @@ -9,6 +9,7 @@ import pydantic | |
| 9 9 | 
             
            class WorkflowPushResponse(UniversalBaseModel):
         | 
| 10 10 | 
             
                workflow_sandbox_id: str
         | 
| 11 11 | 
             
                workflow_deployment_id: typing.Optional[str] = None
         | 
| 12 | 
            +
                proposed_diffs: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = None
         | 
| 12 13 |  | 
| 13 14 | 
             
                if IS_PYDANTIC_V2:
         | 
| 14 15 | 
             
                    model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True)  # type: ignore # Pydantic v2
         | 
| @@ -10,6 +10,12 @@ from vellum import ( | |
| 10 10 | 
             
                StringVellumValue,
         | 
| 11 11 | 
             
                VellumVariable,
         | 
| 12 12 | 
             
            )
         | 
| 13 | 
            +
            from vellum.client.types.audio_vellum_value import AudioVellumValue
         | 
| 14 | 
            +
            from vellum.client.types.function_call import FunctionCall
         | 
| 15 | 
            +
            from vellum.client.types.function_call_vellum_value import FunctionCallVellumValue
         | 
| 16 | 
            +
            from vellum.client.types.image_vellum_value import ImageVellumValue
         | 
| 17 | 
            +
            from vellum.client.types.vellum_audio import VellumAudio
         | 
| 18 | 
            +
            from vellum.client.types.vellum_image import VellumImage
         | 
| 13 19 | 
             
            from vellum.prompts.blocks.exceptions import PromptCompilationError
         | 
| 14 20 | 
             
            from vellum.prompts.blocks.types import CompiledChatMessagePromptBlock, CompiledPromptBlock, CompiledValuePromptBlock
         | 
| 15 21 | 
             
            from vellum.utils.templating.constants import DEFAULT_JINJA_CUSTOM_FILTERS
         | 
| @@ -112,6 +118,43 @@ def compile_prompt_blocks( | |
| 112 118 |  | 
| 113 119 | 
             
                    elif block.block_type == "FUNCTION_DEFINITION":
         | 
| 114 120 | 
             
                        raise PromptCompilationError("Function definitions shouldn't go through compilation process")
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                    elif block.block_type == "FUNCTION_CALL":
         | 
| 123 | 
            +
                        function_call_block = CompiledValuePromptBlock(
         | 
| 124 | 
            +
                            content=FunctionCallVellumValue(
         | 
| 125 | 
            +
                                value=FunctionCall(
         | 
| 126 | 
            +
                                    id=block.id,
         | 
| 127 | 
            +
                                    name=block.name,
         | 
| 128 | 
            +
                                    arguments=block.arguments,
         | 
| 129 | 
            +
                                ),
         | 
| 130 | 
            +
                            ),
         | 
| 131 | 
            +
                            cache_config=block.cache_config,
         | 
| 132 | 
            +
                        )
         | 
| 133 | 
            +
                        compiled_blocks.append(function_call_block)
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                    elif block.block_type == "IMAGE":
         | 
| 136 | 
            +
                        image_block = CompiledValuePromptBlock(
         | 
| 137 | 
            +
                            content=ImageVellumValue(
         | 
| 138 | 
            +
                                value=VellumImage(
         | 
| 139 | 
            +
                                    src=block.src,
         | 
| 140 | 
            +
                                    metadata=block.metadata,
         | 
| 141 | 
            +
                                ),
         | 
| 142 | 
            +
                            ),
         | 
| 143 | 
            +
                            cache_config=block.cache_config,
         | 
| 144 | 
            +
                        )
         | 
| 145 | 
            +
                        compiled_blocks.append(image_block)
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                    elif block.block_type == "AUDIO":
         | 
| 148 | 
            +
                        audio_block = CompiledValuePromptBlock(
         | 
| 149 | 
            +
                            content=AudioVellumValue(
         | 
| 150 | 
            +
                                value=VellumAudio(
         | 
| 151 | 
            +
                                    src=block.src,
         | 
| 152 | 
            +
                                    metadata=block.metadata,
         | 
| 153 | 
            +
                                ),
         | 
| 154 | 
            +
                            ),
         | 
| 155 | 
            +
                            cache_config=block.cache_config,
         | 
| 156 | 
            +
                        )
         | 
| 157 | 
            +
                        compiled_blocks.append(audio_block)
         | 
| 115 158 | 
             
                    else:
         | 
| 116 159 | 
             
                        raise PromptCompilationError(f"Unknown block_type: {block.block_type}")
         | 
| 117 160 |  | 
| @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            from typing import TYPE_CHECKING, ClassVar, Generic, Iterator, Optional, Set, Type, TypeVar, Union
         | 
| 2 2 |  | 
| 3 | 
            +
            from vellum.workflows.constants import UNDEF
         | 
| 3 4 | 
             
            from vellum.workflows.context import execution_context, get_parent_context
         | 
| 4 5 | 
             
            from vellum.workflows.errors.types import WorkflowErrorCode
         | 
| 5 6 | 
             
            from vellum.workflows.exceptions import NodeException
         | 
| @@ -27,7 +28,7 @@ class InlineSubworkflowNode(BaseNode[StateType], Generic[StateType, WorkflowInpu | |
| 27 28 | 
             
                """
         | 
| 28 29 |  | 
| 29 30 | 
             
                subworkflow: Type["BaseWorkflow[WorkflowInputsType, InnerStateType]"]
         | 
| 30 | 
            -
                subworkflow_inputs: ClassVar[Union[EntityInputsInterface, BaseInputs]] =  | 
| 31 | 
            +
                subworkflow_inputs: ClassVar[Union[EntityInputsInterface, BaseInputs, Type[UNDEF]]] = UNDEF
         | 
| 31 32 |  | 
| 32 33 | 
             
                def run(self) -> Iterator[BaseOutput]:
         | 
| 33 34 | 
             
                    with execution_context(parent_context=get_parent_context() or self._context.parent_context):
         | 
| @@ -71,7 +72,14 @@ class InlineSubworkflowNode(BaseNode[StateType], Generic[StateType, WorkflowInpu | |
| 71 72 |  | 
| 72 73 | 
             
                def _compile_subworkflow_inputs(self) -> WorkflowInputsType:
         | 
| 73 74 | 
             
                    inputs_class = self.subworkflow.get_inputs_class()
         | 
| 74 | 
            -
                    if  | 
| 75 | 
            +
                    if self.subworkflow_inputs is UNDEF:
         | 
| 76 | 
            +
                        inputs_dict = {}
         | 
| 77 | 
            +
                        for descriptor in inputs_class:
         | 
| 78 | 
            +
                            if hasattr(self, descriptor.name):
         | 
| 79 | 
            +
                                inputs_dict[descriptor.name] = getattr(self, descriptor.name)
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                        return inputs_class(**inputs_dict)
         | 
| 82 | 
            +
                    elif isinstance(self.subworkflow_inputs, dict):
         | 
| 75 83 | 
             
                        return inputs_class(**self.subworkflow_inputs)
         | 
| 76 84 | 
             
                    elif isinstance(self.subworkflow_inputs, inputs_class):
         | 
| 77 85 | 
             
                        return self.subworkflow_inputs
         | 
| @@ -39,3 +39,19 @@ def test_inline_subworkflow_node__inputs(inputs): | |
| 39 39 | 
             
                assert events == [
         | 
| 40 40 | 
             
                    BaseOutput(name="out", value="bar"),
         | 
| 41 41 | 
             
                ]
         | 
| 42 | 
            +
             | 
| 43 | 
            +
             | 
| 44 | 
            +
            def test_inline_subworkflow_node__support_inputs_as_attributes():
         | 
| 45 | 
            +
                # GIVEN a node setup with subworkflow inputs
         | 
| 46 | 
            +
                class MyNode(InlineSubworkflowNode):
         | 
| 47 | 
            +
                    subworkflow = MySubworkflow
         | 
| 48 | 
            +
                    foo = "bar"
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                # WHEN the node is run
         | 
| 51 | 
            +
                node = MyNode()
         | 
| 52 | 
            +
                events = list(node.run())
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                # THEN the output is as expected
         | 
| 55 | 
            +
                assert events == [
         | 
| 56 | 
            +
                    BaseOutput(name="out", value="bar"),
         | 
| 57 | 
            +
                ]
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Metadata-Version: 2.1
         | 
| 2 2 | 
             
            Name: vellum-ai
         | 
| 3 | 
            -
            Version: 0.12. | 
| 3 | 
            +
            Version: 0.12.16
         | 
| 4 4 | 
             
            Summary: 
         | 
| 5 5 | 
             
            License: MIT
         | 
| 6 6 | 
             
            Requires-Python: >=3.9,<4.0
         | 
| @@ -40,9 +40,11 @@ Requires-Dist: typing_extensions (>=4.0.0) | |
| 40 40 | 
             
            Description-Content-Type: text/markdown
         | 
| 41 41 |  | 
| 42 42 | 
             
            <p align="center">
         | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 43 | 
            +
               <a href="https://vellum.ai">
         | 
| 44 | 
            +
                <picture>
         | 
| 45 | 
            +
                  <img alt="Vellum README banner" src="https://storage.googleapis.com/vellum-public/assets/github-readme-banner.png" height="128">
         | 
| 46 | 
            +
                </picture>
         | 
| 47 | 
            +
              </a>
         | 
| 46 48 | 
             
              <p align="center">
         | 
| 47 49 | 
             
                <a href="https://vellum.ai">Learn more</a>
         | 
| 48 50 | 
             
                ·
         | 
| @@ -64,13 +66,13 @@ Description-Content-Type: text/markdown | |
| 64 66 |  | 
| 65 67 | 
             
            # Introduction
         | 
| 66 68 |  | 
| 67 | 
            -
            [Vellum](https://www.vellum.ai/) is the end-to-end development platform for building production-grade AI applications
         | 
| 69 | 
            +
            [Vellum](https://www.vellum.ai/) is the end-to-end development platform for building production-grade AI applications.
         | 
| 68 70 |  | 
| 69 71 | 
             
            ### Core Features
         | 
| 70 72 |  | 
| 71 73 | 
             
            - **Orchestration:** A powerful SDK and IDE for defining and debugging the control flow of your AI applications
         | 
| 72 74 | 
             
            - **Prompting:** A best-in-class prompt playground for iterating on and refining prompts between models from any provider
         | 
| 73 | 
            -
            - **Evaluations**: An evaluations framework that makes it easy to measure the quality of your AI systems at scale | 
| 75 | 
            +
            - **Evaluations**: An evaluations framework that makes it easy to measure the quality of your AI systems at scale
         | 
| 74 76 | 
             
            - **Retrieval:** A ready-to-go service for turning unstructured content into intelligent, context-aware solutions
         | 
| 75 77 | 
             
              optimized for AI systems
         | 
| 76 78 | 
             
            - **Deployment:** Decouple updates to your AI systems from your application code with an easy integration +
         | 
| @@ -87,7 +89,7 @@ Description-Content-Type: text/markdown | |
| 87 89 |  | 
| 88 90 | 
             
            ## Get Started
         | 
| 89 91 |  | 
| 90 | 
            -
            Most functionality within the  | 
| 92 | 
            +
            Most functionality within the SDK requires a Vellum account and API key. To sign up, [talk to us](https://www.vellum.ai/landing-pages/request-demo)
         | 
| 91 93 | 
             
            or visit our [pricing page](https://www.vellum.ai/pricing).
         | 
| 92 94 |  | 
| 93 95 | 
             
            Even without a Vellum account, you can use the Workflows SDK to define the control flow of your AI systems. [Learn
         | 
| @@ -95,13 +97,13 @@ more below](#workflows-sdk). | |
| 95 97 |  | 
| 96 98 | 
             
            ## Client SDK
         | 
| 97 99 |  | 
| 98 | 
            -
            The Vellum Client SDK, found within `src/client` is a low-level client used to interact directly with the Vellum API.
         | 
| 100 | 
            +
            The Vellum Client SDK, found within `src/vellum/client` is a low-level client used to interact directly with the Vellum API.
         | 
| 99 101 | 
             
            Learn more and get started by visiting the [Vellum Client SDK README](/src/vellum/client/README.md).
         | 
| 100 102 |  | 
| 101 103 | 
             
            ## Workflows SDK
         | 
| 102 104 |  | 
| 103 105 | 
             
            The Vellum Workflows SDK is a high-level framework for defining and debugging the control flow of AI systems. At
         | 
| 104 | 
            -
            it's core, it's a powerful workflow engine with syntactic sugar for  | 
| 106 | 
            +
            it's core, it's a powerful workflow engine with syntactic sugar for declaratively defining graphs, the nodes within,
         | 
| 105 107 | 
             
            and the relationships between them.
         | 
| 106 108 |  | 
| 107 109 | 
             
            The Workflows SDK can be used with or without a Vellum account, but a Vellum account is required to use certain
         |