vellum-ai 0.14.26__py3-none-any.whl → 0.14.28__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 +4 -0
 - vellum/client/__init__.py +4 -0
 - vellum/client/core/client_wrapper.py +1 -1
 - vellum/client/resources/__init__.py +2 -0
 - vellum/client/resources/documents/client.py +0 -14
 - vellum/client/resources/prompts/__init__.py +2 -0
 - vellum/client/resources/prompts/client.py +197 -0
 - vellum/client/types/__init__.py +2 -0
 - vellum/client/types/prompt_exec_config.py +37 -0
 - vellum/resources/prompts/__init__.py +3 -0
 - vellum/resources/prompts/client.py +3 -0
 - vellum/types/prompt_exec_config.py +3 -0
 - vellum/workflows/events/tests/test_event.py +29 -1
 - vellum/workflows/events/types.py +62 -3
 - vellum/workflows/nodes/displayable/code_execution_node/utils.py +3 -2
 - vellum/workflows/nodes/displayable/guardrail_node/node.py +10 -11
 - vellum/workflows/nodes/displayable/guardrail_node/test_node.py +38 -0
 - vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py +13 -2
 - vellum/workflows/runner/runner.py +2 -0
 - {vellum_ai-0.14.26.dist-info → vellum_ai-0.14.28.dist-info}/METADATA +1 -1
 - {vellum_ai-0.14.26.dist-info → vellum_ai-0.14.28.dist-info}/RECORD +28 -21
 - vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +2 -1
 - vellum_ee/workflows/display/nodes/vellum/tests/test_prompt_node.py +80 -1
 - vellum_ee/workflows/server/virtual_file_loader.py +16 -4
 - vellum_ee/workflows/tests/test_server.py +79 -0
 - {vellum_ai-0.14.26.dist-info → vellum_ai-0.14.28.dist-info}/LICENSE +0 -0
 - {vellum_ai-0.14.26.dist-info → vellum_ai-0.14.28.dist-info}/WHEEL +0 -0
 - {vellum_ai-0.14.26.dist-info → vellum_ai-0.14.28.dist-info}/entry_points.txt +0 -0
 
    
        vellum/__init__.py
    CHANGED
    
    | 
         @@ -300,6 +300,7 @@ from .types import ( 
     | 
|
| 
       300 
300 
     | 
    
         
             
                PromptDeploymentExpandMetaRequest,
         
     | 
| 
       301 
301 
     | 
    
         
             
                PromptDeploymentInputRequest,
         
     | 
| 
       302 
302 
     | 
    
         
             
                PromptDeploymentParentContext,
         
     | 
| 
      
 303 
     | 
    
         
            +
                PromptExecConfig,
         
     | 
| 
       303 
304 
     | 
    
         
             
                PromptExecutionMeta,
         
     | 
| 
       304 
305 
     | 
    
         
             
                PromptNodeExecutionMeta,
         
     | 
| 
       305 
306 
     | 
    
         
             
                PromptNodeResult,
         
     | 
| 
         @@ -589,6 +590,7 @@ from .resources import ( 
     | 
|
| 
       589 
590 
     | 
    
         
             
                metric_definitions,
         
     | 
| 
       590 
591 
     | 
    
         
             
                ml_models,
         
     | 
| 
       591 
592 
     | 
    
         
             
                organizations,
         
     | 
| 
      
 593 
     | 
    
         
            +
                prompts,
         
     | 
| 
       592 
594 
     | 
    
         
             
                sandboxes,
         
     | 
| 
       593 
595 
     | 
    
         
             
                test_suite_runs,
         
     | 
| 
       594 
596 
     | 
    
         
             
                test_suites,
         
     | 
| 
         @@ -910,6 +912,7 @@ __all__ = [ 
     | 
|
| 
       910 
912 
     | 
    
         
             
                "PromptDeploymentExpandMetaRequest",
         
     | 
| 
       911 
913 
     | 
    
         
             
                "PromptDeploymentInputRequest",
         
     | 
| 
       912 
914 
     | 
    
         
             
                "PromptDeploymentParentContext",
         
     | 
| 
      
 915 
     | 
    
         
            +
                "PromptExecConfig",
         
     | 
| 
       913 
916 
     | 
    
         
             
                "PromptExecutionMeta",
         
     | 
| 
       914 
917 
     | 
    
         
             
                "PromptNodeExecutionMeta",
         
     | 
| 
       915 
918 
     | 
    
         
             
                "PromptNodeResult",
         
     | 
| 
         @@ -1193,6 +1196,7 @@ __all__ = [ 
     | 
|
| 
       1193 
1196 
     | 
    
         
             
                "metric_definitions",
         
     | 
| 
       1194 
1197 
     | 
    
         
             
                "ml_models",
         
     | 
| 
       1195 
1198 
     | 
    
         
             
                "organizations",
         
     | 
| 
      
 1199 
     | 
    
         
            +
                "prompts",
         
     | 
| 
       1196 
1200 
     | 
    
         
             
                "sandboxes",
         
     | 
| 
       1197 
1201 
     | 
    
         
             
                "test_suite_runs",
         
     | 
| 
       1198 
1202 
     | 
    
         
             
                "test_suites",
         
     | 
    
        vellum/client/__init__.py
    CHANGED
    
    | 
         @@ -13,6 +13,7 @@ from .resources.folder_entities.client import FolderEntitiesClient 
     | 
|
| 
       13 
13 
     | 
    
         
             
            from .resources.metric_definitions.client import MetricDefinitionsClient
         
     | 
| 
       14 
14 
     | 
    
         
             
            from .resources.ml_models.client import MlModelsClient
         
     | 
| 
       15 
15 
     | 
    
         
             
            from .resources.organizations.client import OrganizationsClient
         
     | 
| 
      
 16 
     | 
    
         
            +
            from .resources.prompts.client import PromptsClient
         
     | 
| 
       16 
17 
     | 
    
         
             
            from .resources.sandboxes.client import SandboxesClient
         
     | 
| 
       17 
18 
     | 
    
         
             
            from .resources.test_suite_runs.client import TestSuiteRunsClient
         
     | 
| 
       18 
19 
     | 
    
         
             
            from .resources.test_suites.client import TestSuitesClient
         
     | 
| 
         @@ -69,6 +70,7 @@ from .resources.folder_entities.client import AsyncFolderEntitiesClient 
     | 
|
| 
       69 
70 
     | 
    
         
             
            from .resources.metric_definitions.client import AsyncMetricDefinitionsClient
         
     | 
| 
       70 
71 
     | 
    
         
             
            from .resources.ml_models.client import AsyncMlModelsClient
         
     | 
| 
       71 
72 
     | 
    
         
             
            from .resources.organizations.client import AsyncOrganizationsClient
         
     | 
| 
      
 73 
     | 
    
         
            +
            from .resources.prompts.client import AsyncPromptsClient
         
     | 
| 
       72 
74 
     | 
    
         
             
            from .resources.sandboxes.client import AsyncSandboxesClient
         
     | 
| 
       73 
75 
     | 
    
         
             
            from .resources.test_suite_runs.client import AsyncTestSuiteRunsClient
         
     | 
| 
       74 
76 
     | 
    
         
             
            from .resources.test_suites.client import AsyncTestSuitesClient
         
     | 
| 
         @@ -145,6 +147,7 @@ class Vellum: 
     | 
|
| 
       145 
147 
     | 
    
         
             
                    self.metric_definitions = MetricDefinitionsClient(client_wrapper=self._client_wrapper)
         
     | 
| 
       146 
148 
     | 
    
         
             
                    self.ml_models = MlModelsClient(client_wrapper=self._client_wrapper)
         
     | 
| 
       147 
149 
     | 
    
         
             
                    self.organizations = OrganizationsClient(client_wrapper=self._client_wrapper)
         
     | 
| 
      
 150 
     | 
    
         
            +
                    self.prompts = PromptsClient(client_wrapper=self._client_wrapper)
         
     | 
| 
       148 
151 
     | 
    
         
             
                    self.sandboxes = SandboxesClient(client_wrapper=self._client_wrapper)
         
     | 
| 
       149 
152 
     | 
    
         
             
                    self.test_suite_runs = TestSuiteRunsClient(client_wrapper=self._client_wrapper)
         
     | 
| 
       150 
153 
     | 
    
         
             
                    self.test_suites = TestSuitesClient(client_wrapper=self._client_wrapper)
         
     | 
| 
         @@ -1486,6 +1489,7 @@ class AsyncVellum: 
     | 
|
| 
       1486 
1489 
     | 
    
         
             
                    self.metric_definitions = AsyncMetricDefinitionsClient(client_wrapper=self._client_wrapper)
         
     | 
| 
       1487 
1490 
     | 
    
         
             
                    self.ml_models = AsyncMlModelsClient(client_wrapper=self._client_wrapper)
         
     | 
| 
       1488 
1491 
     | 
    
         
             
                    self.organizations = AsyncOrganizationsClient(client_wrapper=self._client_wrapper)
         
     | 
| 
      
 1492 
     | 
    
         
            +
                    self.prompts = AsyncPromptsClient(client_wrapper=self._client_wrapper)
         
     | 
| 
       1489 
1493 
     | 
    
         
             
                    self.sandboxes = AsyncSandboxesClient(client_wrapper=self._client_wrapper)
         
     | 
| 
       1490 
1494 
     | 
    
         
             
                    self.test_suite_runs = AsyncTestSuiteRunsClient(client_wrapper=self._client_wrapper)
         
     | 
| 
       1491 
1495 
     | 
    
         
             
                    self.test_suites = AsyncTestSuitesClient(client_wrapper=self._client_wrapper)
         
     | 
| 
         @@ -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.28",
         
     | 
| 
       22 
22 
     | 
    
         
             
                    }
         
     | 
| 
       23 
23 
     | 
    
         
             
                    headers["X_API_KEY"] = self.api_key
         
     | 
| 
       24 
24 
     | 
    
         
             
                    return headers
         
     | 
| 
         @@ -10,6 +10,7 @@ from . import ( 
     | 
|
| 
       10 
10 
     | 
    
         
             
                metric_definitions,
         
     | 
| 
       11 
11 
     | 
    
         
             
                ml_models,
         
     | 
| 
       12 
12 
     | 
    
         
             
                organizations,
         
     | 
| 
      
 13 
     | 
    
         
            +
                prompts,
         
     | 
| 
       13 
14 
     | 
    
         
             
                sandboxes,
         
     | 
| 
       14 
15 
     | 
    
         
             
                test_suite_runs,
         
     | 
| 
       15 
16 
     | 
    
         
             
                test_suites,
         
     | 
| 
         @@ -42,6 +43,7 @@ __all__ = [ 
     | 
|
| 
       42 
43 
     | 
    
         
             
                "metric_definitions",
         
     | 
| 
       43 
44 
     | 
    
         
             
                "ml_models",
         
     | 
| 
       44 
45 
     | 
    
         
             
                "organizations",
         
     | 
| 
      
 46 
     | 
    
         
            +
                "prompts",
         
     | 
| 
       45 
47 
     | 
    
         
             
                "sandboxes",
         
     | 
| 
       46 
48 
     | 
    
         
             
                "test_suite_runs",
         
     | 
| 
       47 
49 
     | 
    
         
             
                "test_suites",
         
     | 
| 
         @@ -277,13 +277,6 @@ class DocumentsClient: 
     | 
|
| 
       277 
277 
     | 
    
         | 
| 
       278 
278 
     | 
    
         
             
                    **Note:** Uses a base url of `https://documents.vellum.ai`.
         
     | 
| 
       279 
279 
     | 
    
         | 
| 
       280 
     | 
    
         
            -
                    This is a multipart/form-data request. The `contents` field should be a file upload. It also expects a JSON body with the following fields:
         
     | 
| 
       281 
     | 
    
         
            -
                    - `add_to_index_names: list[str]` - Optionally include the names of all indexes that you'd like this document to be included in
         
     | 
| 
       282 
     | 
    
         
            -
                    - `external_id: str | None` - Optionally include an external ID for this document. This is useful if you want to re-upload the same document later when its contents change and would like it to be re-indexed.
         
     | 
| 
       283 
     | 
    
         
            -
                    - `label: str` - A human-friendly name for this document. Typically the filename.
         
     | 
| 
       284 
     | 
    
         
            -
                    - `keywords: list[str] | None` - Optionally include a list of keywords that'll be associated with this document. Used when performing keyword searches.
         
     | 
| 
       285 
     | 
    
         
            -
                    - `metadata: dict[str, Any]` - A stringified JSON object containing any metadata associated with the document that you'd like to filter upon later.
         
     | 
| 
       286 
     | 
    
         
            -
             
     | 
| 
       287 
280 
     | 
    
         
             
                    Parameters
         
     | 
| 
       288 
281 
     | 
    
         
             
                    ----------
         
     | 
| 
       289 
282 
     | 
    
         
             
                    label : str
         
     | 
| 
         @@ -673,13 +666,6 @@ class AsyncDocumentsClient: 
     | 
|
| 
       673 
666 
     | 
    
         | 
| 
       674 
667 
     | 
    
         
             
                    **Note:** Uses a base url of `https://documents.vellum.ai`.
         
     | 
| 
       675 
668 
     | 
    
         | 
| 
       676 
     | 
    
         
            -
                    This is a multipart/form-data request. The `contents` field should be a file upload. It also expects a JSON body with the following fields:
         
     | 
| 
       677 
     | 
    
         
            -
                    - `add_to_index_names: list[str]` - Optionally include the names of all indexes that you'd like this document to be included in
         
     | 
| 
       678 
     | 
    
         
            -
                    - `external_id: str | None` - Optionally include an external ID for this document. This is useful if you want to re-upload the same document later when its contents change and would like it to be re-indexed.
         
     | 
| 
       679 
     | 
    
         
            -
                    - `label: str` - A human-friendly name for this document. Typically the filename.
         
     | 
| 
       680 
     | 
    
         
            -
                    - `keywords: list[str] | None` - Optionally include a list of keywords that'll be associated with this document. Used when performing keyword searches.
         
     | 
| 
       681 
     | 
    
         
            -
                    - `metadata: dict[str, Any]` - A stringified JSON object containing any metadata associated with the document that you'd like to filter upon later.
         
     | 
| 
       682 
     | 
    
         
            -
             
     | 
| 
       683 
669 
     | 
    
         
             
                    Parameters
         
     | 
| 
       684 
670 
     | 
    
         
             
                    ----------
         
     | 
| 
       685 
671 
     | 
    
         
             
                    label : str
         
     | 
| 
         @@ -0,0 +1,197 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # This file was auto-generated by Fern from our API Definition.
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            from ...core.client_wrapper import SyncClientWrapper
         
     | 
| 
      
 4 
     | 
    
         
            +
            import typing
         
     | 
| 
      
 5 
     | 
    
         
            +
            from ...core.request_options import RequestOptions
         
     | 
| 
      
 6 
     | 
    
         
            +
            from ...types.prompt_exec_config import PromptExecConfig
         
     | 
| 
      
 7 
     | 
    
         
            +
            from ...core.jsonable_encoder import jsonable_encoder
         
     | 
| 
      
 8 
     | 
    
         
            +
            from ...core.pydantic_utilities import parse_obj_as
         
     | 
| 
      
 9 
     | 
    
         
            +
            from ...errors.bad_request_error import BadRequestError
         
     | 
| 
      
 10 
     | 
    
         
            +
            from ...errors.not_found_error import NotFoundError
         
     | 
| 
      
 11 
     | 
    
         
            +
            from json.decoder import JSONDecodeError
         
     | 
| 
      
 12 
     | 
    
         
            +
            from ...core.api_error import ApiError
         
     | 
| 
      
 13 
     | 
    
         
            +
            from ...core.client_wrapper import AsyncClientWrapper
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            class PromptsClient:
         
     | 
| 
      
 17 
     | 
    
         
            +
                def __init__(self, *, client_wrapper: SyncClientWrapper):
         
     | 
| 
      
 18 
     | 
    
         
            +
                    self._client_wrapper = client_wrapper
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def pull(
         
     | 
| 
      
 21 
     | 
    
         
            +
                    self,
         
     | 
| 
      
 22 
     | 
    
         
            +
                    id: str,
         
     | 
| 
      
 23 
     | 
    
         
            +
                    *,
         
     | 
| 
      
 24 
     | 
    
         
            +
                    prompt_variant_id: typing.Optional[str] = None,
         
     | 
| 
      
 25 
     | 
    
         
            +
                    request_options: typing.Optional[RequestOptions] = None,
         
     | 
| 
      
 26 
     | 
    
         
            +
                ) -> PromptExecConfig:
         
     | 
| 
      
 27 
     | 
    
         
            +
                    """
         
     | 
| 
      
 28 
     | 
    
         
            +
                    Used to pull the definition of a Prompt from Vellum.
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                    Parameters
         
     | 
| 
      
 31 
     | 
    
         
            +
                    ----------
         
     | 
| 
      
 32 
     | 
    
         
            +
                    id : str
         
     | 
| 
      
 33 
     | 
    
         
            +
                        The ID of the Prompt to pull from. Prompt Sandbox IDs are currently supported.
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    prompt_variant_id : typing.Optional[str]
         
     | 
| 
      
 36 
     | 
    
         
            +
                        The ID of the Prompt Variant within a Prompt Sandbox to pull. Must be included if providing the ID of a Prompt Sandbox.
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                    request_options : typing.Optional[RequestOptions]
         
     | 
| 
      
 39 
     | 
    
         
            +
                        Request-specific configuration.
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                    Returns
         
     | 
| 
      
 42 
     | 
    
         
            +
                    -------
         
     | 
| 
      
 43 
     | 
    
         
            +
                    PromptExecConfig
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                    Examples
         
     | 
| 
      
 47 
     | 
    
         
            +
                    --------
         
     | 
| 
      
 48 
     | 
    
         
            +
                    from vellum import Vellum
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    client = Vellum(
         
     | 
| 
      
 51 
     | 
    
         
            +
                        api_key="YOUR_API_KEY",
         
     | 
| 
      
 52 
     | 
    
         
            +
                    )
         
     | 
| 
      
 53 
     | 
    
         
            +
                    client.prompts.pull(
         
     | 
| 
      
 54 
     | 
    
         
            +
                        id="id",
         
     | 
| 
      
 55 
     | 
    
         
            +
                    )
         
     | 
| 
      
 56 
     | 
    
         
            +
                    """
         
     | 
| 
      
 57 
     | 
    
         
            +
                    _response = self._client_wrapper.httpx_client.request(
         
     | 
| 
      
 58 
     | 
    
         
            +
                        f"v1/prompts/{jsonable_encoder(id)}/pull",
         
     | 
| 
      
 59 
     | 
    
         
            +
                        base_url=self._client_wrapper.get_environment().default,
         
     | 
| 
      
 60 
     | 
    
         
            +
                        method="GET",
         
     | 
| 
      
 61 
     | 
    
         
            +
                        params={
         
     | 
| 
      
 62 
     | 
    
         
            +
                            "prompt_variant_id": prompt_variant_id,
         
     | 
| 
      
 63 
     | 
    
         
            +
                        },
         
     | 
| 
      
 64 
     | 
    
         
            +
                        headers={
         
     | 
| 
      
 65 
     | 
    
         
            +
                            "Accept": "application/json",
         
     | 
| 
      
 66 
     | 
    
         
            +
                        },
         
     | 
| 
      
 67 
     | 
    
         
            +
                        request_options=request_options,
         
     | 
| 
      
 68 
     | 
    
         
            +
                    )
         
     | 
| 
      
 69 
     | 
    
         
            +
                    try:
         
     | 
| 
      
 70 
     | 
    
         
            +
                        if 200 <= _response.status_code < 300:
         
     | 
| 
      
 71 
     | 
    
         
            +
                            return typing.cast(
         
     | 
| 
      
 72 
     | 
    
         
            +
                                PromptExecConfig,
         
     | 
| 
      
 73 
     | 
    
         
            +
                                parse_obj_as(
         
     | 
| 
      
 74 
     | 
    
         
            +
                                    type_=PromptExecConfig,  # type: ignore
         
     | 
| 
      
 75 
     | 
    
         
            +
                                    object_=_response.json(),
         
     | 
| 
      
 76 
     | 
    
         
            +
                                ),
         
     | 
| 
      
 77 
     | 
    
         
            +
                            )
         
     | 
| 
      
 78 
     | 
    
         
            +
                        if _response.status_code == 400:
         
     | 
| 
      
 79 
     | 
    
         
            +
                            raise BadRequestError(
         
     | 
| 
      
 80 
     | 
    
         
            +
                                typing.cast(
         
     | 
| 
      
 81 
     | 
    
         
            +
                                    typing.Optional[typing.Any],
         
     | 
| 
      
 82 
     | 
    
         
            +
                                    parse_obj_as(
         
     | 
| 
      
 83 
     | 
    
         
            +
                                        type_=typing.Optional[typing.Any],  # type: ignore
         
     | 
| 
      
 84 
     | 
    
         
            +
                                        object_=_response.json(),
         
     | 
| 
      
 85 
     | 
    
         
            +
                                    ),
         
     | 
| 
      
 86 
     | 
    
         
            +
                                )
         
     | 
| 
      
 87 
     | 
    
         
            +
                            )
         
     | 
| 
      
 88 
     | 
    
         
            +
                        if _response.status_code == 404:
         
     | 
| 
      
 89 
     | 
    
         
            +
                            raise NotFoundError(
         
     | 
| 
      
 90 
     | 
    
         
            +
                                typing.cast(
         
     | 
| 
      
 91 
     | 
    
         
            +
                                    typing.Optional[typing.Any],
         
     | 
| 
      
 92 
     | 
    
         
            +
                                    parse_obj_as(
         
     | 
| 
      
 93 
     | 
    
         
            +
                                        type_=typing.Optional[typing.Any],  # type: ignore
         
     | 
| 
      
 94 
     | 
    
         
            +
                                        object_=_response.json(),
         
     | 
| 
      
 95 
     | 
    
         
            +
                                    ),
         
     | 
| 
      
 96 
     | 
    
         
            +
                                )
         
     | 
| 
      
 97 
     | 
    
         
            +
                            )
         
     | 
| 
      
 98 
     | 
    
         
            +
                        _response_json = _response.json()
         
     | 
| 
      
 99 
     | 
    
         
            +
                    except JSONDecodeError:
         
     | 
| 
      
 100 
     | 
    
         
            +
                        raise ApiError(status_code=_response.status_code, body=_response.text)
         
     | 
| 
      
 101 
     | 
    
         
            +
                    raise ApiError(status_code=_response.status_code, body=_response_json)
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            class AsyncPromptsClient:
         
     | 
| 
      
 105 
     | 
    
         
            +
                def __init__(self, *, client_wrapper: AsyncClientWrapper):
         
     | 
| 
      
 106 
     | 
    
         
            +
                    self._client_wrapper = client_wrapper
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                async def pull(
         
     | 
| 
      
 109 
     | 
    
         
            +
                    self,
         
     | 
| 
      
 110 
     | 
    
         
            +
                    id: str,
         
     | 
| 
      
 111 
     | 
    
         
            +
                    *,
         
     | 
| 
      
 112 
     | 
    
         
            +
                    prompt_variant_id: typing.Optional[str] = None,
         
     | 
| 
      
 113 
     | 
    
         
            +
                    request_options: typing.Optional[RequestOptions] = None,
         
     | 
| 
      
 114 
     | 
    
         
            +
                ) -> PromptExecConfig:
         
     | 
| 
      
 115 
     | 
    
         
            +
                    """
         
     | 
| 
      
 116 
     | 
    
         
            +
                    Used to pull the definition of a Prompt from Vellum.
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                    Parameters
         
     | 
| 
      
 119 
     | 
    
         
            +
                    ----------
         
     | 
| 
      
 120 
     | 
    
         
            +
                    id : str
         
     | 
| 
      
 121 
     | 
    
         
            +
                        The ID of the Prompt to pull from. Prompt Sandbox IDs are currently supported.
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                    prompt_variant_id : typing.Optional[str]
         
     | 
| 
      
 124 
     | 
    
         
            +
                        The ID of the Prompt Variant within a Prompt Sandbox to pull. Must be included if providing the ID of a Prompt Sandbox.
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                    request_options : typing.Optional[RequestOptions]
         
     | 
| 
      
 127 
     | 
    
         
            +
                        Request-specific configuration.
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                    Returns
         
     | 
| 
      
 130 
     | 
    
         
            +
                    -------
         
     | 
| 
      
 131 
     | 
    
         
            +
                    PromptExecConfig
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                    Examples
         
     | 
| 
      
 135 
     | 
    
         
            +
                    --------
         
     | 
| 
      
 136 
     | 
    
         
            +
                    import asyncio
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                    from vellum import AsyncVellum
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                    client = AsyncVellum(
         
     | 
| 
      
 141 
     | 
    
         
            +
                        api_key="YOUR_API_KEY",
         
     | 
| 
      
 142 
     | 
    
         
            +
                    )
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                    async def main() -> None:
         
     | 
| 
      
 146 
     | 
    
         
            +
                        await client.prompts.pull(
         
     | 
| 
      
 147 
     | 
    
         
            +
                            id="id",
         
     | 
| 
      
 148 
     | 
    
         
            +
                        )
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                    asyncio.run(main())
         
     | 
| 
      
 152 
     | 
    
         
            +
                    """
         
     | 
| 
      
 153 
     | 
    
         
            +
                    _response = await self._client_wrapper.httpx_client.request(
         
     | 
| 
      
 154 
     | 
    
         
            +
                        f"v1/prompts/{jsonable_encoder(id)}/pull",
         
     | 
| 
      
 155 
     | 
    
         
            +
                        base_url=self._client_wrapper.get_environment().default,
         
     | 
| 
      
 156 
     | 
    
         
            +
                        method="GET",
         
     | 
| 
      
 157 
     | 
    
         
            +
                        params={
         
     | 
| 
      
 158 
     | 
    
         
            +
                            "prompt_variant_id": prompt_variant_id,
         
     | 
| 
      
 159 
     | 
    
         
            +
                        },
         
     | 
| 
      
 160 
     | 
    
         
            +
                        headers={
         
     | 
| 
      
 161 
     | 
    
         
            +
                            "Accept": "application/json",
         
     | 
| 
      
 162 
     | 
    
         
            +
                        },
         
     | 
| 
      
 163 
     | 
    
         
            +
                        request_options=request_options,
         
     | 
| 
      
 164 
     | 
    
         
            +
                    )
         
     | 
| 
      
 165 
     | 
    
         
            +
                    try:
         
     | 
| 
      
 166 
     | 
    
         
            +
                        if 200 <= _response.status_code < 300:
         
     | 
| 
      
 167 
     | 
    
         
            +
                            return typing.cast(
         
     | 
| 
      
 168 
     | 
    
         
            +
                                PromptExecConfig,
         
     | 
| 
      
 169 
     | 
    
         
            +
                                parse_obj_as(
         
     | 
| 
      
 170 
     | 
    
         
            +
                                    type_=PromptExecConfig,  # type: ignore
         
     | 
| 
      
 171 
     | 
    
         
            +
                                    object_=_response.json(),
         
     | 
| 
      
 172 
     | 
    
         
            +
                                ),
         
     | 
| 
      
 173 
     | 
    
         
            +
                            )
         
     | 
| 
      
 174 
     | 
    
         
            +
                        if _response.status_code == 400:
         
     | 
| 
      
 175 
     | 
    
         
            +
                            raise BadRequestError(
         
     | 
| 
      
 176 
     | 
    
         
            +
                                typing.cast(
         
     | 
| 
      
 177 
     | 
    
         
            +
                                    typing.Optional[typing.Any],
         
     | 
| 
      
 178 
     | 
    
         
            +
                                    parse_obj_as(
         
     | 
| 
      
 179 
     | 
    
         
            +
                                        type_=typing.Optional[typing.Any],  # type: ignore
         
     | 
| 
      
 180 
     | 
    
         
            +
                                        object_=_response.json(),
         
     | 
| 
      
 181 
     | 
    
         
            +
                                    ),
         
     | 
| 
      
 182 
     | 
    
         
            +
                                )
         
     | 
| 
      
 183 
     | 
    
         
            +
                            )
         
     | 
| 
      
 184 
     | 
    
         
            +
                        if _response.status_code == 404:
         
     | 
| 
      
 185 
     | 
    
         
            +
                            raise NotFoundError(
         
     | 
| 
      
 186 
     | 
    
         
            +
                                typing.cast(
         
     | 
| 
      
 187 
     | 
    
         
            +
                                    typing.Optional[typing.Any],
         
     | 
| 
      
 188 
     | 
    
         
            +
                                    parse_obj_as(
         
     | 
| 
      
 189 
     | 
    
         
            +
                                        type_=typing.Optional[typing.Any],  # type: ignore
         
     | 
| 
      
 190 
     | 
    
         
            +
                                        object_=_response.json(),
         
     | 
| 
      
 191 
     | 
    
         
            +
                                    ),
         
     | 
| 
      
 192 
     | 
    
         
            +
                                )
         
     | 
| 
      
 193 
     | 
    
         
            +
                            )
         
     | 
| 
      
 194 
     | 
    
         
            +
                        _response_json = _response.json()
         
     | 
| 
      
 195 
     | 
    
         
            +
                    except JSONDecodeError:
         
     | 
| 
      
 196 
     | 
    
         
            +
                        raise ApiError(status_code=_response.status_code, body=_response.text)
         
     | 
| 
      
 197 
     | 
    
         
            +
                    raise ApiError(status_code=_response.status_code, body=_response_json)
         
     | 
    
        vellum/client/types/__init__.py
    CHANGED
    
    | 
         @@ -308,6 +308,7 @@ from .prompt_block_state import PromptBlockState 
     | 
|
| 
       308 
308 
     | 
    
         
             
            from .prompt_deployment_expand_meta_request import PromptDeploymentExpandMetaRequest
         
     | 
| 
       309 
309 
     | 
    
         
             
            from .prompt_deployment_input_request import PromptDeploymentInputRequest
         
     | 
| 
       310 
310 
     | 
    
         
             
            from .prompt_deployment_parent_context import PromptDeploymentParentContext
         
     | 
| 
      
 311 
     | 
    
         
            +
            from .prompt_exec_config import PromptExecConfig
         
     | 
| 
       311 
312 
     | 
    
         
             
            from .prompt_execution_meta import PromptExecutionMeta
         
     | 
| 
       312 
313 
     | 
    
         
             
            from .prompt_node_execution_meta import PromptNodeExecutionMeta
         
     | 
| 
       313 
314 
     | 
    
         
             
            from .prompt_node_result import PromptNodeResult
         
     | 
| 
         @@ -892,6 +893,7 @@ __all__ = [ 
     | 
|
| 
       892 
893 
     | 
    
         
             
                "PromptDeploymentExpandMetaRequest",
         
     | 
| 
       893 
894 
     | 
    
         
             
                "PromptDeploymentInputRequest",
         
     | 
| 
       894 
895 
     | 
    
         
             
                "PromptDeploymentParentContext",
         
     | 
| 
      
 896 
     | 
    
         
            +
                "PromptExecConfig",
         
     | 
| 
       895 
897 
     | 
    
         
             
                "PromptExecutionMeta",
         
     | 
| 
       896 
898 
     | 
    
         
             
                "PromptNodeExecutionMeta",
         
     | 
| 
       897 
899 
     | 
    
         
             
                "PromptNodeResult",
         
     | 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # This file was auto-generated by Fern from our API Definition.
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            from __future__ import annotations
         
     | 
| 
      
 4 
     | 
    
         
            +
            from ..core.pydantic_utilities import UniversalBaseModel
         
     | 
| 
      
 5 
     | 
    
         
            +
            from .array_vellum_value import ArrayVellumValue
         
     | 
| 
      
 6 
     | 
    
         
            +
            from .chat_message_prompt_block import ChatMessagePromptBlock
         
     | 
| 
      
 7 
     | 
    
         
            +
            import typing
         
     | 
| 
      
 8 
     | 
    
         
            +
            from .vellum_variable import VellumVariable
         
     | 
| 
      
 9 
     | 
    
         
            +
            from .prompt_parameters import PromptParameters
         
     | 
| 
      
 10 
     | 
    
         
            +
            from .prompt_settings import PromptSettings
         
     | 
| 
      
 11 
     | 
    
         
            +
            from .prompt_block import PromptBlock
         
     | 
| 
      
 12 
     | 
    
         
            +
            from .function_definition import FunctionDefinition
         
     | 
| 
      
 13 
     | 
    
         
            +
            from ..core.pydantic_utilities import IS_PYDANTIC_V2
         
     | 
| 
      
 14 
     | 
    
         
            +
            import pydantic
         
     | 
| 
      
 15 
     | 
    
         
            +
            from ..core.pydantic_utilities import update_forward_refs
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            class PromptExecConfig(UniversalBaseModel):
         
     | 
| 
      
 19 
     | 
    
         
            +
                ml_model: str
         
     | 
| 
      
 20 
     | 
    
         
            +
                input_variables: typing.List[VellumVariable]
         
     | 
| 
      
 21 
     | 
    
         
            +
                parameters: PromptParameters
         
     | 
| 
      
 22 
     | 
    
         
            +
                settings: typing.Optional[PromptSettings] = None
         
     | 
| 
      
 23 
     | 
    
         
            +
                blocks: typing.List[PromptBlock]
         
     | 
| 
      
 24 
     | 
    
         
            +
                functions: typing.Optional[typing.List[FunctionDefinition]] = None
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                if IS_PYDANTIC_V2:
         
     | 
| 
      
 27 
     | 
    
         
            +
                    model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True)  # type: ignore # Pydantic v2
         
     | 
| 
      
 28 
     | 
    
         
            +
                else:
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                    class Config:
         
     | 
| 
      
 31 
     | 
    
         
            +
                        frozen = True
         
     | 
| 
      
 32 
     | 
    
         
            +
                        smart_union = True
         
     | 
| 
      
 33 
     | 
    
         
            +
                        extra = pydantic.Extra.allow
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            update_forward_refs(ArrayVellumValue, PromptExecConfig=PromptExecConfig)
         
     | 
| 
      
 37 
     | 
    
         
            +
            update_forward_refs(ChatMessagePromptBlock, PromptExecConfig=PromptExecConfig)
         
     | 
| 
         @@ -4,6 +4,7 @@ from uuid import UUID 
     | 
|
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            from deepdiff import DeepDiff
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
      
 7 
     | 
    
         
            +
            from vellum.client.core.pydantic_utilities import UniversalBaseModel
         
     | 
| 
       7 
8 
     | 
    
         
             
            from vellum.workflows.constants import undefined
         
     | 
| 
       8 
9 
     | 
    
         
             
            from vellum.workflows.errors.types import WorkflowError, WorkflowErrorCode
         
     | 
| 
       9 
10 
     | 
    
         
             
            from vellum.workflows.events.node import (
         
     | 
| 
         @@ -14,7 +15,7 @@ from vellum.workflows.events.node import ( 
     | 
|
| 
       14 
15 
     | 
    
         
             
                NodeExecutionStreamingBody,
         
     | 
| 
       15 
16 
     | 
    
         
             
                NodeExecutionStreamingEvent,
         
     | 
| 
       16 
17 
     | 
    
         
             
            )
         
     | 
| 
       17 
     | 
    
         
            -
            from vellum.workflows.events.types import NodeParentContext, WorkflowParentContext
         
     | 
| 
      
 18 
     | 
    
         
            +
            from vellum.workflows.events.types import NodeParentContext, ParentContext, WorkflowParentContext
         
     | 
| 
       18 
19 
     | 
    
         
             
            from vellum.workflows.events.workflow import (
         
     | 
| 
       19 
20 
     | 
    
         
             
                WorkflowExecutionFulfilledBody,
         
     | 
| 
       20 
21 
     | 
    
         
             
                WorkflowExecutionFulfilledEvent,
         
     | 
| 
         @@ -419,3 +420,30 @@ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__)) 
     | 
|
| 
       419 
420 
     | 
    
         
             
            )
         
     | 
| 
       420 
421 
     | 
    
         
             
            def test_event_serialization(event, expected_json):
         
     | 
| 
       421 
422 
     | 
    
         
             
                assert not DeepDiff(event.model_dump(mode="json"), expected_json)
         
     | 
| 
      
 423 
     | 
    
         
            +
             
     | 
| 
      
 424 
     | 
    
         
            +
             
     | 
| 
      
 425 
     | 
    
         
            +
            def test_parent_context__deserialize_from_json__invalid_parent_context():
         
     | 
| 
      
 426 
     | 
    
         
            +
                # GIVEN an event with a parent context that Vellum is introducing in the future
         
     | 
| 
      
 427 
     | 
    
         
            +
                data = {
         
     | 
| 
      
 428 
     | 
    
         
            +
                    "foo": "bar",
         
     | 
| 
      
 429 
     | 
    
         
            +
                    "parent": {
         
     | 
| 
      
 430 
     | 
    
         
            +
                        "type": "SOME_FUTURE_ENTITY",
         
     | 
| 
      
 431 
     | 
    
         
            +
                        "span_id": "123e4567-e89b-12d3-a456-426614174000",
         
     | 
| 
      
 432 
     | 
    
         
            +
                        "some_randome_field": "some_random_value",
         
     | 
| 
      
 433 
     | 
    
         
            +
                        "parent": None,
         
     | 
| 
      
 434 
     | 
    
         
            +
                    },
         
     | 
| 
      
 435 
     | 
    
         
            +
                }
         
     | 
| 
      
 436 
     | 
    
         
            +
             
     | 
| 
      
 437 
     | 
    
         
            +
                # AND a dataclass that references the parent context
         
     | 
| 
      
 438 
     | 
    
         
            +
                class MyData(UniversalBaseModel):
         
     | 
| 
      
 439 
     | 
    
         
            +
                    foo: str
         
     | 
| 
      
 440 
     | 
    
         
            +
                    parent: ParentContext
         
     | 
| 
      
 441 
     | 
    
         
            +
             
     | 
| 
      
 442 
     | 
    
         
            +
                # WHEN the data is deserialized
         
     | 
| 
      
 443 
     | 
    
         
            +
                event = MyData.model_validate(data)
         
     | 
| 
      
 444 
     | 
    
         
            +
             
     | 
| 
      
 445 
     | 
    
         
            +
                # THEN the event is deserialized correctly
         
     | 
| 
      
 446 
     | 
    
         
            +
                assert event.parent
         
     | 
| 
      
 447 
     | 
    
         
            +
                assert event.parent.type == "UNKNOWN"
         
     | 
| 
      
 448 
     | 
    
         
            +
                assert event.parent.span_id == UUID("123e4567-e89b-12d3-a456-426614174000")
         
     | 
| 
      
 449 
     | 
    
         
            +
                assert event.parent.parent is None
         
     | 
    
        vellum/workflows/events/types.py
    CHANGED
    
    | 
         @@ -1,9 +1,10 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            from datetime import datetime
         
     | 
| 
       2 
2 
     | 
    
         
             
            import json
         
     | 
| 
       3 
3 
     | 
    
         
             
            from uuid import UUID, uuid4
         
     | 
| 
       4 
     | 
    
         
            -
            from typing import Annotated, Any, Dict, List, Literal, Optional, Union
         
     | 
| 
      
 4 
     | 
    
         
            +
            from typing import Annotated, Any, Dict, List, Literal, Optional, Union, get_args
         
     | 
| 
       5 
5 
     | 
    
         | 
| 
       6 
     | 
    
         
            -
            from pydantic import BeforeValidator, Field
         
     | 
| 
      
 6 
     | 
    
         
            +
            from pydantic import BeforeValidator, Field, GetCoreSchemaHandler, Tag, ValidationInfo
         
     | 
| 
      
 7 
     | 
    
         
            +
            from pydantic_core import CoreSchema, core_schema
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
9 
     | 
    
         
             
            from vellum.core.pydantic_utilities import UniversalBaseModel
         
     | 
| 
       9 
10 
     | 
    
         
             
            from vellum.workflows.state.encoder import DefaultStateEncoder
         
     | 
| 
         @@ -112,6 +113,59 @@ class APIRequestParentContext(BaseParentContext): 
     | 
|
| 
       112 
113 
     | 
    
         
             
                type: Literal["API_REQUEST"] = "API_REQUEST"
         
     | 
| 
       113 
114 
     | 
    
         | 
| 
       114 
115 
     | 
    
         | 
| 
      
 116 
     | 
    
         
            +
            class UnknownParentContext(BaseParentContext):
         
     | 
| 
      
 117 
     | 
    
         
            +
                type: Literal["UNKNOWN"] = "UNKNOWN"
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            def _cast_parent_context_discriminator(v: Any) -> Any:
         
     | 
| 
      
 121 
     | 
    
         
            +
                if v in PARENT_CONTEXT_TYPES:
         
     | 
| 
      
 122 
     | 
    
         
            +
                    return v
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                return "UNKNOWN"
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
            def _get_parent_context_discriminator(v: Any) -> Any:
         
     | 
| 
      
 128 
     | 
    
         
            +
                if isinstance(v, dict) and "type" in v:
         
     | 
| 
      
 129 
     | 
    
         
            +
                    return _cast_parent_context_discriminator(v["type"])
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                if isinstance(v, PARENT_CONTEXT_CHOICES):
         
     | 
| 
      
 132 
     | 
    
         
            +
                    return v.type
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                return _cast_parent_context_discriminator(v)
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
            def _tag_parent_context_discriminator(v: Any) -> Any:
         
     | 
| 
      
 138 
     | 
    
         
            +
                return Tag(_get_parent_context_discriminator(v))
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
            def _validate_parent_context_discriminator(v: Any, info: ValidationInfo) -> Any:
         
     | 
| 
      
 142 
     | 
    
         
            +
                if isinstance(v, str):
         
     | 
| 
      
 143 
     | 
    
         
            +
                    return _get_parent_context_discriminator(v)
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                if isinstance(v, dict) and "type" in v:
         
     | 
| 
      
 146 
     | 
    
         
            +
                    v["type"] = _get_parent_context_discriminator(v["type"])
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                return v
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
            class ParentContextDiscriminator:
         
     | 
| 
      
 152 
     | 
    
         
            +
                def __get_pydantic_core_schema__(self, source_type: Any, handler: GetCoreSchemaHandler) -> CoreSchema:
         
     | 
| 
      
 153 
     | 
    
         
            +
                    original_schema = handler(source_type)
         
     | 
| 
      
 154 
     | 
    
         
            +
                    tagged_union_choices = {}
         
     | 
| 
      
 155 
     | 
    
         
            +
                    for index, choice in enumerate(original_schema["choices"]):
         
     | 
| 
      
 156 
     | 
    
         
            +
                        tagged_union_choices[Tag(PARENT_CONTEXT_TYPES[index])] = choice
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                    tagged_union_schema = core_schema.tagged_union_schema(
         
     | 
| 
      
 159 
     | 
    
         
            +
                        tagged_union_choices,
         
     | 
| 
      
 160 
     | 
    
         
            +
                        _tag_parent_context_discriminator,
         
     | 
| 
      
 161 
     | 
    
         
            +
                    )
         
     | 
| 
      
 162 
     | 
    
         
            +
                    return core_schema.with_info_before_validator_function(
         
     | 
| 
      
 163 
     | 
    
         
            +
                        function=_validate_parent_context_discriminator,
         
     | 
| 
      
 164 
     | 
    
         
            +
                        schema=tagged_union_schema,
         
     | 
| 
      
 165 
     | 
    
         
            +
                        field_name="type",
         
     | 
| 
      
 166 
     | 
    
         
            +
                    )
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
       115 
169 
     | 
    
         
             
            # Define the discriminated union
         
     | 
| 
       116 
170 
     | 
    
         
             
            ParentContext = Annotated[
         
     | 
| 
       117 
171 
     | 
    
         
             
                Union[
         
     | 
| 
         @@ -121,8 +175,13 @@ ParentContext = Annotated[ 
     | 
|
| 
       121 
175 
     | 
    
         
             
                    PromptDeploymentParentContext,
         
     | 
| 
       122 
176 
     | 
    
         
             
                    WorkflowSandboxParentContext,
         
     | 
| 
       123 
177 
     | 
    
         
             
                    APIRequestParentContext,
         
     | 
| 
      
 178 
     | 
    
         
            +
                    UnknownParentContext,
         
     | 
| 
       124 
179 
     | 
    
         
             
                ],
         
     | 
| 
       125 
     | 
    
         
            -
                 
     | 
| 
      
 180 
     | 
    
         
            +
                ParentContextDiscriminator(),
         
     | 
| 
      
 181 
     | 
    
         
            +
            ]
         
     | 
| 
      
 182 
     | 
    
         
            +
            PARENT_CONTEXT_CHOICES = get_args(get_args(ParentContext)[0])
         
     | 
| 
      
 183 
     | 
    
         
            +
            PARENT_CONTEXT_TYPES = [
         
     | 
| 
      
 184 
     | 
    
         
            +
                pc.model_fields["type"].default for pc in PARENT_CONTEXT_CHOICES if issubclass(pc, UniversalBaseModel)
         
     | 
| 
       126 
185 
     | 
    
         
             
            ]
         
     | 
| 
       127 
186 
     | 
    
         | 
| 
       128 
187 
     | 
    
         
             
            # Update the forward references
         
     | 
| 
         @@ -14,10 +14,11 @@ def read_file_from_path(node_filepath: str, script_filepath: str) -> Union[str, 
     | 
|
| 
       14 
14 
     | 
    
         
             
                node_filepath_dir = os.path.dirname(node_filepath)
         
     | 
| 
       15 
15 
     | 
    
         
             
                full_filepath = os.path.join(node_filepath_dir, script_filepath)
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
                 
     | 
| 
      
 17 
     | 
    
         
            +
                try:
         
     | 
| 
       18 
18 
     | 
    
         
             
                    with open(full_filepath) as file:
         
     | 
| 
       19 
19 
     | 
    
         
             
                        return file.read()
         
     | 
| 
       20 
     | 
    
         
            -
                 
     | 
| 
      
 20 
     | 
    
         
            +
                except (FileNotFoundError, IsADirectoryError):
         
     | 
| 
      
 21 
     | 
    
         
            +
                    return None
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
23 
     | 
    
         | 
| 
       23 
24 
     | 
    
         
             
            class ListWrapper(list):
         
     | 
| 
         @@ -52,19 +52,18 @@ class GuardrailNode(BaseNode[StateType], Generic[StateType]): 
     | 
|
| 
       52 
52 
     | 
    
         
             
                            message="Metric execution must have one output named 'score' with type 'float'",
         
     | 
| 
       53 
53 
     | 
    
         
             
                            code=WorkflowErrorCode.INVALID_OUTPUTS,
         
     | 
| 
       54 
54 
     | 
    
         
             
                        )
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
                    log = metric_outputs.get("log")
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
                    if log is not None and not isinstance(log, str):
         
     | 
| 
       59 
     | 
    
         
            -
                        raise NodeException(
         
     | 
| 
       60 
     | 
    
         
            -
                            message="Metric execution log output must be of type 'str'",
         
     | 
| 
       61 
     | 
    
         
            -
                            code=WorkflowErrorCode.INVALID_OUTPUTS,
         
     | 
| 
       62 
     | 
    
         
            -
                        )
         
     | 
| 
       63 
     | 
    
         
            -
                    if log:
         
     | 
| 
       64 
     | 
    
         
            -
                        metric_outputs.pop("log")
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
55 
     | 
    
         
             
                    metric_outputs.pop("score")
         
     | 
| 
       67 
56 
     | 
    
         | 
| 
      
 57 
     | 
    
         
            +
                    if "log" in metric_outputs:
         
     | 
| 
      
 58 
     | 
    
         
            +
                        log = metric_outputs.pop("log") or ""
         
     | 
| 
      
 59 
     | 
    
         
            +
                        if not isinstance(log, str):
         
     | 
| 
      
 60 
     | 
    
         
            +
                            raise NodeException(
         
     | 
| 
      
 61 
     | 
    
         
            +
                                message="Metric execution log output must be of type 'str'",
         
     | 
| 
      
 62 
     | 
    
         
            +
                                code=WorkflowErrorCode.INVALID_OUTPUTS,
         
     | 
| 
      
 63 
     | 
    
         
            +
                            )
         
     | 
| 
      
 64 
     | 
    
         
            +
                    else:
         
     | 
| 
      
 65 
     | 
    
         
            +
                        log = None
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
       68 
67 
     | 
    
         
             
                    return self.Outputs(score=score, log=log, **metric_outputs)
         
     | 
| 
       69 
68 
     | 
    
         | 
| 
       70 
69 
     | 
    
         
             
                def _compile_metric_inputs(self) -> List[MetricDefinitionInput]:
         
     | 
| 
         @@ -0,0 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import pytest
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            from vellum import TestSuiteRunMetricNumberOutput
         
     | 
| 
      
 4 
     | 
    
         
            +
            from vellum.client.types.metric_definition_execution import MetricDefinitionExecution
         
     | 
| 
      
 5 
     | 
    
         
            +
            from vellum.client.types.test_suite_run_metric_string_output import TestSuiteRunMetricStringOutput
         
     | 
| 
      
 6 
     | 
    
         
            +
            from vellum.workflows.nodes.displayable.guardrail_node.node import GuardrailNode
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            @pytest.mark.parametrize("log_value", [None, ""], ids=["None", "Empty"])
         
     | 
| 
      
 10 
     | 
    
         
            +
            def test_run_guardrail_node__empty_log(vellum_client, log_value):
         
     | 
| 
      
 11 
     | 
    
         
            +
                """Confirm that we can successfully invoke a Guardrail Node"""
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                # GIVEN a Guardrail Node
         
     | 
| 
      
 14 
     | 
    
         
            +
                class MyGuard(GuardrailNode):
         
     | 
| 
      
 15 
     | 
    
         
            +
                    metric_definition = "example_metric_definition"
         
     | 
| 
      
 16 
     | 
    
         
            +
                    metric_inputs = {}
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                # AND we know that the guardrail node will return a blank log
         
     | 
| 
      
 19 
     | 
    
         
            +
                mock_metric_execution = MetricDefinitionExecution(
         
     | 
| 
      
 20 
     | 
    
         
            +
                    outputs=[
         
     | 
| 
      
 21 
     | 
    
         
            +
                        TestSuiteRunMetricNumberOutput(
         
     | 
| 
      
 22 
     | 
    
         
            +
                            name="score",
         
     | 
| 
      
 23 
     | 
    
         
            +
                            value=0.6,
         
     | 
| 
      
 24 
     | 
    
         
            +
                        ),
         
     | 
| 
      
 25 
     | 
    
         
            +
                        TestSuiteRunMetricStringOutput(
         
     | 
| 
      
 26 
     | 
    
         
            +
                            name="log",
         
     | 
| 
      
 27 
     | 
    
         
            +
                            value=log_value,
         
     | 
| 
      
 28 
     | 
    
         
            +
                        ),
         
     | 
| 
      
 29 
     | 
    
         
            +
                    ],
         
     | 
| 
      
 30 
     | 
    
         
            +
                )
         
     | 
| 
      
 31 
     | 
    
         
            +
                vellum_client.metric_definitions.execute_metric_definition.return_value = mock_metric_execution
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                # WHEN we run the Guardrail Node
         
     | 
| 
      
 34 
     | 
    
         
            +
                outputs = MyGuard().run()
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                # THEN the workflow should have completed successfully
         
     | 
| 
      
 37 
     | 
    
         
            +
                assert outputs.score == 0.6
         
     | 
| 
      
 38 
     | 
    
         
            +
                assert outputs.log == ""
         
     | 
| 
         @@ -9,6 +9,7 @@ from httpx import Response 
     | 
|
| 
       9 
9 
     | 
    
         
             
            from vellum.client.core.api_error import ApiError
         
     | 
| 
       10 
10 
     | 
    
         
             
            from vellum.client.core.pydantic_utilities import UniversalBaseModel
         
     | 
| 
       11 
11 
     | 
    
         
             
            from vellum.client.types.chat_message import ChatMessage
         
     | 
| 
      
 12 
     | 
    
         
            +
            from vellum.client.types.chat_message_prompt_block import ChatMessagePromptBlock
         
     | 
| 
       12 
13 
     | 
    
         
             
            from vellum.client.types.chat_message_request import ChatMessageRequest
         
     | 
| 
       13 
14 
     | 
    
         
             
            from vellum.client.types.execute_prompt_event import ExecutePromptEvent
         
     | 
| 
       14 
15 
     | 
    
         
             
            from vellum.client.types.fulfilled_execute_prompt_event import FulfilledExecutePromptEvent
         
     | 
| 
         @@ -241,7 +242,7 @@ def test_inline_prompt_node__parent_context(mock_httpx_transport, mock_complex_p 
     | 
|
| 
       241 
242 
     | 
    
         
             
                # GIVEN a prompt node
         
     | 
| 
       242 
243 
     | 
    
         
             
                class MyNode(InlinePromptNode):
         
     | 
| 
       243 
244 
     | 
    
         
             
                    ml_model = "gpt-4o"
         
     | 
| 
       244 
     | 
    
         
            -
                    blocks = []
         
     | 
| 
      
 245 
     | 
    
         
            +
                    blocks = [ChatMessagePromptBlock(chat_role="USER", blocks=[])]
         
     | 
| 
       245 
246 
     | 
    
         
             
                    prompt_inputs = {}
         
     | 
| 
       246 
247 
     | 
    
         | 
| 
       247 
248 
     | 
    
         
             
                # AND a known response from the httpx client
         
     | 
| 
         @@ -276,6 +277,16 @@ def test_inline_prompt_node__parent_context(mock_httpx_transport, mock_complex_p 
     | 
|
| 
       276 
277 
     | 
    
         | 
| 
       277 
278 
     | 
    
         
             
                # AND the prompt is executed with the correct execution context
         
     | 
| 
       278 
279 
     | 
    
         
             
                call_request_args = mock_httpx_transport.handle_request.call_args_list[0][0][0]
         
     | 
| 
       279 
     | 
    
         
            -
                 
     | 
| 
      
 280 
     | 
    
         
            +
                call_request = json.loads(call_request_args.read().decode("utf-8"))
         
     | 
| 
      
 281 
     | 
    
         
            +
                request_execution_context = call_request["execution_context"]
         
     | 
| 
       280 
282 
     | 
    
         
             
                assert request_execution_context["trace_id"] == str(trace_id)
         
     | 
| 
       281 
283 
     | 
    
         
             
                assert request_execution_context["parent_context"]
         
     | 
| 
      
 284 
     | 
    
         
            +
             
     | 
| 
      
 285 
     | 
    
         
            +
                # AND the blocks are serialized as expected
         
     | 
| 
      
 286 
     | 
    
         
            +
                assert call_request["blocks"] == [
         
     | 
| 
      
 287 
     | 
    
         
            +
                    {
         
     | 
| 
      
 288 
     | 
    
         
            +
                        "block_type": "CHAT_MESSAGE",
         
     | 
| 
      
 289 
     | 
    
         
            +
                        "chat_role": "USER",
         
     | 
| 
      
 290 
     | 
    
         
            +
                        "blocks": [],
         
     | 
| 
      
 291 
     | 
    
         
            +
                    }
         
     | 
| 
      
 292 
     | 
    
         
            +
                ]
         
     | 
| 
         @@ -321,6 +321,7 @@ class WorkflowRunner(Generic[StateType]): 
     | 
|
| 
       321 
321 
     | 
    
         
             
                            )
         
     | 
| 
       322 
322 
     | 
    
         
             
                        )
         
     | 
| 
       323 
323 
     | 
    
         
             
                    except NodeException as e:
         
     | 
| 
      
 324 
     | 
    
         
            +
                        logger.info(e)
         
     | 
| 
       324 
325 
     | 
    
         
             
                        self._workflow_event_inner_queue.put(
         
     | 
| 
       325 
326 
     | 
    
         
             
                            NodeExecutionRejectedEvent(
         
     | 
| 
       326 
327 
     | 
    
         
             
                                trace_id=node.state.meta.trace_id,
         
     | 
| 
         @@ -333,6 +334,7 @@ class WorkflowRunner(Generic[StateType]): 
     | 
|
| 
       333 
334 
     | 
    
         
             
                            )
         
     | 
| 
       334 
335 
     | 
    
         
             
                        )
         
     | 
| 
       335 
336 
     | 
    
         
             
                    except WorkflowInitializationException as e:
         
     | 
| 
      
 337 
     | 
    
         
            +
                        logger.info(e)
         
     | 
| 
       336 
338 
     | 
    
         
             
                        self._workflow_event_inner_queue.put(
         
     | 
| 
       337 
339 
     | 
    
         
             
                            NodeExecutionRejectedEvent(
         
     | 
| 
       338 
340 
     | 
    
         
             
                                trace_id=node.state.meta.trace_id,
         
     | 
| 
         @@ -41,7 +41,7 @@ vellum_ee/workflows/display/nodes/vellum/conditional_node.py,sha256=ybLIa4uclqVI 
     | 
|
| 
       41 
41 
     | 
    
         
             
            vellum_ee/workflows/display/nodes/vellum/error_node.py,sha256=I1Jkp2htRINJATtv1e-zs9BrReFX842djpiVgBPHDYg,2186
         
     | 
| 
       42 
42 
     | 
    
         
             
            vellum_ee/workflows/display/nodes/vellum/final_output_node.py,sha256=BJ--Y-LCbGFJve3OFEKHVxrw8TKvgb342opYLJibToc,3128
         
     | 
| 
       43 
43 
     | 
    
         
             
            vellum_ee/workflows/display/nodes/vellum/guardrail_node.py,sha256=aYZSJTxknU4LMiQdWk9LcK6CkhdozeDEMiRxfAyUNEc,2202
         
     | 
| 
       44 
     | 
    
         
            -
            vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256= 
     | 
| 
      
 44 
     | 
    
         
            +
            vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py,sha256=86hkneLIBS4Jel3GWsPVIIFqXGD3RHIpXw0iGa_Zues,8843
         
     | 
| 
       45 
45 
     | 
    
         
             
            vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py,sha256=MU9I8CB1X1TgL1aa1eT6DHWwNJ-2v79t74xl0oy-fBo,5510
         
     | 
| 
       46 
46 
     | 
    
         
             
            vellum_ee/workflows/display/nodes/vellum/map_node.py,sha256=8CPnn06HIBxBOiECevUffeVmQmCpec6WtPQnNl9gj9Y,3748
         
     | 
| 
       47 
47 
     | 
    
         
             
            vellum_ee/workflows/display/nodes/vellum/merge_node.py,sha256=xtyecs9mJ_WEwVpP12jxYwvehLXynhqLrPJ-Ahdk2GA,3232
         
     | 
| 
         @@ -54,7 +54,7 @@ vellum_ee/workflows/display/nodes/vellum/templating_node.py,sha256=5EWzdA3TSUPlb 
     | 
|
| 
       54 
54 
     | 
    
         
             
            vellum_ee/workflows/display/nodes/vellum/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       55 
55 
     | 
    
         
             
            vellum_ee/workflows/display/nodes/vellum/tests/test_code_execution_node.py,sha256=p0fCvbKzpGvVrg67QmJd14m9E8_DG0u5s6SYIhzlkNA,4018
         
     | 
| 
       56 
56 
     | 
    
         
             
            vellum_ee/workflows/display/nodes/vellum/tests/test_error_node.py,sha256=ulrpoYUW-5kIxfG4Lf5F2p0k_EoYKhmahEbF3P_eruM,1648
         
     | 
| 
       57 
     | 
    
         
            -
            vellum_ee/workflows/display/nodes/vellum/tests/test_prompt_node.py,sha256= 
     | 
| 
      
 57 
     | 
    
         
            +
            vellum_ee/workflows/display/nodes/vellum/tests/test_prompt_node.py,sha256=fu9nxD4FInSfKbipJJ7UE617VkeUWs_uS6SeEz_8-Iw,4691
         
     | 
| 
       58 
58 
     | 
    
         
             
            vellum_ee/workflows/display/nodes/vellum/tests/test_retry_node.py,sha256=NuIw8Yb42KUdoGi3Ur8_7VPg50IC4hNrwAkCociwqNk,2091
         
     | 
| 
       59 
59 
     | 
    
         
             
            vellum_ee/workflows/display/nodes/vellum/tests/test_templating_node.py,sha256=Us32jf_FQnLuT4Bs2o5JyHxihCTAN8ozZghWIR0pl9k,3459
         
     | 
| 
       60 
60 
     | 
    
         
             
            vellum_ee/workflows/display/nodes/vellum/tests/test_try_node.py,sha256=mtzB8LJlFCHVFM4H5AanLp29gQfaVmnN4A4iaRGJHoI,2427
         
     | 
| 
         @@ -100,7 +100,7 @@ vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py,sha25 
     | 
|
| 
       100 
100 
     | 
    
         
             
            vellum_ee/workflows/display/workflows/tests/test_workflow_display.py,sha256=nD6_lZnNp56siVJwhlWzSEHdMaSKjvWlsJa31SqfQAE,10623
         
     | 
| 
       101 
101 
     | 
    
         
             
            vellum_ee/workflows/display/workflows/vellum_workflow_display.py,sha256=AzGZ7ApiwXAHuymTJoXJketUegyC1dmB1blzoni5eh8,13423
         
     | 
| 
       102 
102 
     | 
    
         
             
            vellum_ee/workflows/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       103 
     | 
    
         
            -
            vellum_ee/workflows/server/virtual_file_loader.py,sha256= 
     | 
| 
      
 103 
     | 
    
         
            +
            vellum_ee/workflows/server/virtual_file_loader.py,sha256=7JphJcSO3H85qiC2DpFfBWjC3JjrbRmoynBC6KKHVsA,2710
         
     | 
| 
       104 
104 
     | 
    
         
             
            vellum_ee/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       105 
105 
     | 
    
         
             
            vellum_ee/workflows/tests/local_files/__init__.py,sha256=UyP6kKkRqr9cTKHQF4MVLdLk5MM9GGcLuqxXsQGm22Y,51
         
     | 
| 
       106 
106 
     | 
    
         
             
            vellum_ee/workflows/tests/local_files/base_class.py,sha256=UuiC7J68MVr6A4949QYiBpXOLdsvFG_Cw1muEPiHT6I,298
         
     | 
| 
         @@ -121,14 +121,14 @@ vellum_ee/workflows/tests/local_workflow/nodes/final_output.py,sha256=ZX7zBv87zi 
     | 
|
| 
       121 
121 
     | 
    
         
             
            vellum_ee/workflows/tests/local_workflow/nodes/templating_node.py,sha256=NQwFN61QkHfI3Vssz-B0NKGfupK8PU0FDSAIAhYBLi0,325
         
     | 
| 
       122 
122 
     | 
    
         
             
            vellum_ee/workflows/tests/local_workflow/workflow.py,sha256=A4qOzOPNwePYxWbcAgIPLsmrVS_aVEZEc-wULSv787Q,393
         
     | 
| 
       123 
123 
     | 
    
         
             
            vellum_ee/workflows/tests/test_display_meta.py,sha256=C25dErwghPNXio49pvSRxyOuc96srH6eYEwTAWdE2zY,2258
         
     | 
| 
       124 
     | 
    
         
            -
            vellum_ee/workflows/tests/test_server.py,sha256= 
     | 
| 
      
 124 
     | 
    
         
            +
            vellum_ee/workflows/tests/test_server.py,sha256=Ll4o9gg0Q4r8uX6Kt8LWgIz0u2zLwPiZxl3TuqoZpxg,4707
         
     | 
| 
       125 
125 
     | 
    
         
             
            vellum_ee/workflows/tests/test_virtual_files.py,sha256=TJEcMR0v2S8CkloXNmCHA0QW0K6pYNGaIjraJz7sFvY,2762
         
     | 
| 
       126 
     | 
    
         
            -
            vellum/__init__.py,sha256= 
     | 
| 
      
 126 
     | 
    
         
            +
            vellum/__init__.py,sha256=88-79I29hBTQvR1uH_BOCGMWuj2a4Nx82R_8KIESg28,40470
         
     | 
| 
       127 
127 
     | 
    
         
             
            vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
         
     | 
| 
       128 
     | 
    
         
            -
            vellum/client/__init__.py,sha256= 
     | 
| 
      
 128 
     | 
    
         
            +
            vellum/client/__init__.py,sha256=Jv9sI5BNFo2OYA9px_aREFSIp655ryC3eaZSRI6yH1k,117826
         
     | 
| 
       129 
129 
     | 
    
         
             
            vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
         
     | 
| 
       130 
130 
     | 
    
         
             
            vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
         
     | 
| 
       131 
     | 
    
         
            -
            vellum/client/core/client_wrapper.py,sha256= 
     | 
| 
      
 131 
     | 
    
         
            +
            vellum/client/core/client_wrapper.py,sha256=UH9Mq4cJvem6l6xfFj0IWt_RPwlM-wLXpcS5F1LSo2k,1869
         
     | 
| 
       132 
132 
     | 
    
         
             
            vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
         
     | 
| 
       133 
133 
     | 
    
         
             
            vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
         
     | 
| 
       134 
134 
     | 
    
         
             
            vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
         
     | 
| 
         @@ -144,7 +144,7 @@ vellum/client/errors/bad_request_error.py,sha256=_EbO8mWqN9kFZPvIap8qa1lL_EWkRcs 
     | 
|
| 
       144 
144 
     | 
    
         
             
            vellum/client/errors/forbidden_error.py,sha256=QO1kKlhClAPES6zsEK7g9pglWnxn3KWaOCAawWOg6Aw,263
         
     | 
| 
       145 
145 
     | 
    
         
             
            vellum/client/errors/internal_server_error.py,sha256=8USCagXyJJ1MOm9snpcXIUt6eNXvrd_aq7Gfcu1vlOI,268
         
     | 
| 
       146 
146 
     | 
    
         
             
            vellum/client/errors/not_found_error.py,sha256=tBVCeBC8n3C811WHRj_n-hs3h8MqwR5gp0vLiobk7W8,262
         
     | 
| 
       147 
     | 
    
         
            -
            vellum/client/resources/__init__.py,sha256= 
     | 
| 
      
 147 
     | 
    
         
            +
            vellum/client/resources/__init__.py,sha256=UcVAa7Iwo6e5ijqrraBlDlUA5wnXYVfRMJwXGJkz8UM,1511
         
     | 
| 
       148 
148 
     | 
    
         
             
            vellum/client/resources/ad_hoc/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
         
     | 
| 
       149 
149 
     | 
    
         
             
            vellum/client/resources/ad_hoc/client.py,sha256=_liorv4AsoJ55kVu0a5oWB3Qeff0iUKXqoHEIyDWLxc,14173
         
     | 
| 
       150 
150 
     | 
    
         
             
            vellum/client/resources/container_images/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
         
     | 
| 
         @@ -159,7 +159,7 @@ vellum/client/resources/document_indexes/client.py,sha256=UcznU0NyvdNBpV4UCsTqG3 
     | 
|
| 
       159 
159 
     | 
    
         
             
            vellum/client/resources/document_indexes/types/__init__.py,sha256=IoFqKHN_VBdEhC7VL8_6Jbatrn0e0zuYEJAJUahcUR0,196
         
     | 
| 
       160 
160 
     | 
    
         
             
            vellum/client/resources/document_indexes/types/document_indexes_list_request_status.py,sha256=sfUEB0cvOSmlE2iITqnMVyHv05Zy2fWP4QjCIYqMg0M,178
         
     | 
| 
       161 
161 
     | 
    
         
             
            vellum/client/resources/documents/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
         
     | 
| 
       162 
     | 
    
         
            -
            vellum/client/resources/documents/client.py,sha256= 
     | 
| 
      
 162 
     | 
    
         
            +
            vellum/client/resources/documents/client.py,sha256=DOiZ0i0iuGxPWTxDZsd8kndZPMB4GslHvyj1gBkrTIc,26048
         
     | 
| 
       163 
163 
     | 
    
         
             
            vellum/client/resources/folder_entities/__init__.py,sha256=QOp7UMMB3a32GrfVaud35ECn4fqPBKXxCyClsDgd6GE,175
         
     | 
| 
       164 
164 
     | 
    
         
             
            vellum/client/resources/folder_entities/client.py,sha256=xkT6D1TwPxvf1eXgDhRpKg7_O2V78jwBsIGyJgnI5SY,11110
         
     | 
| 
       165 
165 
     | 
    
         
             
            vellum/client/resources/folder_entities/types/__init__.py,sha256=cHabrupjC-HL3kj-UZ9WdVzqHoQHCu6QsLFB3wlOs7k,212
         
     | 
| 
         @@ -170,6 +170,8 @@ vellum/client/resources/ml_models/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8 
     | 
|
| 
       170 
170 
     | 
    
         
             
            vellum/client/resources/ml_models/client.py,sha256=XIYapTEY6GRNr7V0Kjy5bEeKmrhv9ul8qlQY2A5LFqQ,3872
         
     | 
| 
       171 
171 
     | 
    
         
             
            vellum/client/resources/organizations/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
         
     | 
| 
       172 
172 
     | 
    
         
             
            vellum/client/resources/organizations/client.py,sha256=Uye92moqjAcOCs4astmuFpT92QdC5SLMunA-C8_G-gA,3675
         
     | 
| 
      
 173 
     | 
    
         
            +
            vellum/client/resources/prompts/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
         
     | 
| 
      
 174 
     | 
    
         
            +
            vellum/client/resources/prompts/client.py,sha256=_rNTUjhl_ZF3vyQa_M1BSTrX4DlFXU_SXkwwCEYKD2s,6598
         
     | 
| 
       173 
175 
     | 
    
         
             
            vellum/client/resources/sandboxes/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
         
     | 
| 
       174 
176 
     | 
    
         
             
            vellum/client/resources/sandboxes/client.py,sha256=i-6DHap5k6gFcYS-kWI8ayJFVZxb-GENRft6BJwVam4,17158
         
     | 
| 
       175 
177 
     | 
    
         
             
            vellum/client/resources/test_suite_runs/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
         
     | 
| 
         @@ -191,7 +193,7 @@ vellum/client/resources/workspace_secrets/__init__.py,sha256=FTtvy8EDg9nNNg9WCat 
     | 
|
| 
       191 
193 
     | 
    
         
             
            vellum/client/resources/workspace_secrets/client.py,sha256=h7UzXLyTttPq1t-JZGMg1BWxypxJvBGUdqg7KGT7MK4,8027
         
     | 
| 
       192 
194 
     | 
    
         
             
            vellum/client/resources/workspaces/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
         
     | 
| 
       193 
195 
     | 
    
         
             
            vellum/client/resources/workspaces/client.py,sha256=RthwzN1o-Jxwg5yyNNodavFyNUSxfLoTv26w3mRR5g8,3595
         
     | 
| 
       194 
     | 
    
         
            -
            vellum/client/types/__init__.py,sha256= 
     | 
| 
      
 196 
     | 
    
         
            +
            vellum/client/types/__init__.py,sha256=MUfv33R5OwoLX1dHVETCtWFNM3Xz-jWPJ2Z8ZrXlLqM,61259
         
     | 
| 
       195 
197 
     | 
    
         
             
            vellum/client/types/ad_hoc_execute_prompt_event.py,sha256=bCjujA2XsOgyF3bRZbcEqV2rOIymRgsLoIRtZpB14xg,607
         
     | 
| 
       196 
198 
     | 
    
         
             
            vellum/client/types/ad_hoc_expand_meta.py,sha256=1gv-NCsy_6xBYupLvZH979yf2VMdxAU-l0y0ynMKZaw,1331
         
     | 
| 
       197 
199 
     | 
    
         
             
            vellum/client/types/ad_hoc_fulfilled_prompt_execution_meta.py,sha256=Bfvf1d_dkmshxRACVM5vcxbH_7AQY23RmrrnPc0ytYY,939
         
     | 
| 
         @@ -488,6 +490,7 @@ vellum/client/types/prompt_block_state.py,sha256=BRAzTYARoSU36IVZGWMeeqhl5fgFMXC 
     | 
|
| 
       488 
490 
     | 
    
         
             
            vellum/client/types/prompt_deployment_expand_meta_request.py,sha256=agsiAaHB6lDoZPlnfJ2nmhB4Ud4EiJJTX05YmduyCPo,1910
         
     | 
| 
       489 
491 
     | 
    
         
             
            vellum/client/types/prompt_deployment_input_request.py,sha256=KrT4-Ew2VvTWXEkYQz2oyHn5EDOgrMW7FzRFaPH3ARg,353
         
     | 
| 
       490 
492 
     | 
    
         
             
            vellum/client/types/prompt_deployment_parent_context.py,sha256=eu8dYmRb789uZeFVzbRkJrErDYZXo35f2qaNBcY0wOQ,2319
         
     | 
| 
      
 493 
     | 
    
         
            +
            vellum/client/types/prompt_exec_config.py,sha256=kthvyEe-IzfTpOBd1fYrczHuxD-v7k6cwjmuaY170RQ,1390
         
     | 
| 
       491 
494 
     | 
    
         
             
            vellum/client/types/prompt_execution_meta.py,sha256=3hhMZgdAR5mKfnh2e_eVN3oKfT0E9w26khVPrpjn7jk,1141
         
     | 
| 
       492 
495 
     | 
    
         
             
            vellum/client/types/prompt_node_execution_meta.py,sha256=IyWH__nCp5uwS0N32b2ZEsA-Fv7AZDB4nnlRZayU2Gc,888
         
     | 
| 
       493 
496 
     | 
    
         
             
            vellum/client/types/prompt_node_result.py,sha256=3jewO-nPodoXTq_5RxgwhKfDZrvoPjRZ_vUXLeqiuHY,749
         
     | 
| 
         @@ -822,6 +825,8 @@ vellum/resources/ml_models/__init__.py,sha256=qIepoIEWDHz3u7i0bW3jnTpdTdfPGhA1LB 
     | 
|
| 
       822 
825 
     | 
    
         
             
            vellum/resources/ml_models/client.py,sha256=RSYFEe1BnFTDBMur2_eR3ZkLZbdWeTGe_OIuMwcsfdw,158
         
     | 
| 
       823 
826 
     | 
    
         
             
            vellum/resources/organizations/__init__.py,sha256=FD1umjszsErkQIAI6aZ7Lv_T6iN5IafeCbgv25uIpYo,155
         
     | 
| 
       824 
827 
     | 
    
         
             
            vellum/resources/organizations/client.py,sha256=68HAX4pswpJDH0-Yjc3teoloSJBUGRv8O1V8tCqFSuk,162
         
     | 
| 
      
 828 
     | 
    
         
            +
            vellum/resources/prompts/__init__.py,sha256=CtN_jI0nc0C3yqxUPR1uWs5Mvxhlce5c-d8E96GVt4g,149
         
     | 
| 
      
 829 
     | 
    
         
            +
            vellum/resources/prompts/client.py,sha256=9S00NNuuiz41m6-kOL6KCxu9bnYMORrXrXVWfFEeW5o,156
         
     | 
| 
       825 
830 
     | 
    
         
             
            vellum/resources/sandboxes/__init__.py,sha256=sycp4Bgvj9GzBGjiXhtmKFjOdBsIoDfMFaQrvDK_lGo,151
         
     | 
| 
       826 
831 
     | 
    
         
             
            vellum/resources/sandboxes/client.py,sha256=PBpYOg43HN-9B4YKtPqmE1aFag39ypLc5UWSxixUJjo,158
         
     | 
| 
       827 
832 
     | 
    
         
             
            vellum/resources/test_suite_runs/__init__.py,sha256=PfRYjodfN_rYZlUTiBnVXxdwQNcdmI-qT6MCqubd3ug,157
         
     | 
| 
         @@ -1140,6 +1145,7 @@ vellum/types/prompt_block_state.py,sha256=tKqNrZnHWjvfGS_6oIUTpdCPGxvRJa31Le6qWL 
     | 
|
| 
       1140 
1145 
     | 
    
         
             
            vellum/types/prompt_deployment_expand_meta_request.py,sha256=5dBdvjjK9zCKxrPMdKQPj6iG8A06GAlb_zazde6qZsU,175
         
     | 
| 
       1141 
1146 
     | 
    
         
             
            vellum/types/prompt_deployment_input_request.py,sha256=z8CxCZWnKW8BBZajQ6iDnz-2gaxU-FrnYrVe_MvC3FU,169
         
     | 
| 
       1142 
1147 
     | 
    
         
             
            vellum/types/prompt_deployment_parent_context.py,sha256=U9X9PvXhG6ZUE8RxLrH13xfqKvs3DOwbxzWmujoXTbg,170
         
     | 
| 
      
 1148 
     | 
    
         
            +
            vellum/types/prompt_exec_config.py,sha256=aNeOGDi6l2rVzvkFt8CJE6L3W2EmY8gZaSb5051w8as,156
         
     | 
| 
       1143 
1149 
     | 
    
         
             
            vellum/types/prompt_execution_meta.py,sha256=_5izDjusf-TM69zKhvXr5EHH4Fx9jfWkg8F5_KNJV-w,159
         
     | 
| 
       1144 
1150 
     | 
    
         
             
            vellum/types/prompt_node_execution_meta.py,sha256=cJoHlIn_lb_sLpQniB8eszRJvFI6mJij9QgUIiKtiCY,164
         
     | 
| 
       1145 
1151 
     | 
    
         
             
            vellum/types/prompt_node_result.py,sha256=9ootTTh8lscQ-0WE0-bqdmn7XFvpP7uavO-g7mPkA3Q,156
         
     | 
| 
         @@ -1441,8 +1447,8 @@ vellum/workflows/errors/types.py,sha256=tVW7Il9zalnwWzdoDLqYPIvRTOhXIv6FPORZAbU7 
     | 
|
| 
       1441 
1447 
     | 
    
         
             
            vellum/workflows/events/__init__.py,sha256=6pxxceJo2dcaRkWtkDAYlUQZ-PHBQSZytIoyuUK48Qw,759
         
     | 
| 
       1442 
1448 
     | 
    
         
             
            vellum/workflows/events/node.py,sha256=jbmNHjdp331Q1IRK-AWtAxwF6Lidb9R7__N5rQuilE8,5401
         
     | 
| 
       1443 
1449 
     | 
    
         
             
            vellum/workflows/events/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       1444 
     | 
    
         
            -
            vellum/workflows/events/tests/test_event.py,sha256= 
     | 
| 
       1445 
     | 
    
         
            -
            vellum/workflows/events/types.py,sha256= 
     | 
| 
      
 1450 
     | 
    
         
            +
            vellum/workflows/events/tests/test_event.py,sha256=WRxjOO1470rFH40O56RWjhonIdupW782h_FRAhIQZCQ,17823
         
     | 
| 
      
 1451 
     | 
    
         
            +
            vellum/workflows/events/types.py,sha256=cKXEZEZ4C_O38CH-qiu8nYSMy2DVJ66lQayJO5A-haU,5690
         
     | 
| 
       1446 
1452 
     | 
    
         
             
            vellum/workflows/events/workflow.py,sha256=xdqU6WOexaAqzJbU2Zw42o2LJhK7SDPtTFO5REGv17I,7293
         
     | 
| 
       1447 
1453 
     | 
    
         
             
            vellum/workflows/exceptions.py,sha256=NiBiR3ggfmPxBVqD-H1SqmjI-7mIn0EStSN1BqApvCM,1213
         
     | 
| 
       1448 
1454 
     | 
    
         
             
            vellum/workflows/expressions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
         @@ -1542,7 +1548,7 @@ vellum/workflows/nodes/displayable/code_execution_node/tests/__init__.py,sha256= 
     | 
|
| 
       1542 
1548 
     | 
    
         
             
            vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       1543 
1549 
     | 
    
         
             
            vellum/workflows/nodes/displayable/code_execution_node/tests/fixtures/main.py,sha256=5QsbmkzSlSbcbWTG_JmIqcP-JNJzOPTKxGzdHos19W4,79
         
     | 
| 
       1544 
1550 
     | 
    
         
             
            vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py,sha256=xAaoOfQHQUlp0iKlig87t0aT2cJM-8PxiTb1QDg8VmY,24641
         
     | 
| 
       1545 
     | 
    
         
            -
            vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256= 
     | 
| 
      
 1551 
     | 
    
         
            +
            vellum/workflows/nodes/displayable/code_execution_node/utils.py,sha256=PI0IQysC3uASv4nof23O4gIWpoNl3tRleb1q417bfTw,3896
         
     | 
| 
       1546 
1552 
     | 
    
         
             
            vellum/workflows/nodes/displayable/conditional_node/__init__.py,sha256=AS_EIqFdU1F9t8aLmbZU-rLh9ry6LCJ0uj0D8F0L5Uw,72
         
     | 
| 
       1547 
1553 
     | 
    
         
             
            vellum/workflows/nodes/displayable/conditional_node/node.py,sha256=Qjfl33gZ3JEgxBA1EgzSUebboGvsARthIxxcQyvx5Gg,1152
         
     | 
| 
       1548 
1554 
     | 
    
         
             
            vellum/workflows/nodes/displayable/conftest.py,sha256=tD_WIiw5WjFqnzgnGLtEZDaMj2XhQ1DptnBTKYeBbI0,5705
         
     | 
| 
         @@ -1551,11 +1557,12 @@ vellum/workflows/nodes/displayable/final_output_node/node.py,sha256=PuQ0RvtAmoSI 
     | 
|
| 
       1551 
1557 
     | 
    
         
             
            vellum/workflows/nodes/displayable/final_output_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       1552 
1558 
     | 
    
         
             
            vellum/workflows/nodes/displayable/final_output_node/tests/test_node.py,sha256=E6LQ74qZjY4Xi4avx2qdOCgGhF8pEcNLBh8cqYRkzMI,709
         
     | 
| 
       1553 
1559 
     | 
    
         
             
            vellum/workflows/nodes/displayable/guardrail_node/__init__.py,sha256=Ab5eXmOoBhyV4dMWdzh32HLUmnPIBEK_zFCT38C4Fng,68
         
     | 
| 
       1554 
     | 
    
         
            -
            vellum/workflows/nodes/displayable/guardrail_node/node.py,sha256= 
     | 
| 
      
 1560 
     | 
    
         
            +
            vellum/workflows/nodes/displayable/guardrail_node/node.py,sha256=YMXBLHB4_TYWGvbWMQP2WH0ckktK1uFDOEYkRJc-RfE,4422
         
     | 
| 
      
 1561 
     | 
    
         
            +
            vellum/workflows/nodes/displayable/guardrail_node/test_node.py,sha256=1yPIAt4_GWiUKT6u3rTW2XKp62b8xG8Jj3JWeCm5ZDM,1368
         
     | 
| 
       1555 
1562 
     | 
    
         
             
            vellum/workflows/nodes/displayable/inline_prompt_node/__init__.py,sha256=gSUOoEZLlrx35-tQhSAd3An8WDwBqyiQh-sIebLU9wU,74
         
     | 
| 
       1556 
1563 
     | 
    
         
             
            vellum/workflows/nodes/displayable/inline_prompt_node/node.py,sha256=8RXZqWMzViUjFfbpmcy1gkSsKnEpci8BGwsuPYv4xMQ,3380
         
     | 
| 
       1557 
1564 
     | 
    
         
             
            vellum/workflows/nodes/displayable/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       1558 
     | 
    
         
            -
            vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py,sha256= 
     | 
| 
      
 1565 
     | 
    
         
            +
            vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py,sha256=D06GymJGoMt9StKpTzqYk8wvmRedkvcRdYUHPUznvK4,10554
         
     | 
| 
       1559 
1566 
     | 
    
         
             
            vellum/workflows/nodes/displayable/merge_node/__init__.py,sha256=J8IC08dSH7P76wKlNuxe1sn7toNGtSQdFirUbtPDEs0,60
         
     | 
| 
       1560 
1567 
     | 
    
         
             
            vellum/workflows/nodes/displayable/merge_node/node.py,sha256=nZtGGVAvY4fvGg8vwV6sTQ8_QLRnigeXt0vf2FL272A,450
         
     | 
| 
       1561 
1568 
     | 
    
         
             
            vellum/workflows/nodes/displayable/note_node/__init__.py,sha256=KWA3P4fyYJ-fOTky8qNGlcOotQ-HeHJ9AjZt6mRQmCE,58
         
     | 
| 
         @@ -1607,7 +1614,7 @@ vellum/workflows/references/workflow_input.py,sha256=lq7BiiLBHQNP-vP2p1TN2QBq0_L 
     | 
|
| 
       1607 
1614 
     | 
    
         
             
            vellum/workflows/resolvers/__init__.py,sha256=eH6hTvZO4IciDaf_cf7aM2vs-DkBDyJPycOQevJxQnI,82
         
     | 
| 
       1608 
1615 
     | 
    
         
             
            vellum/workflows/resolvers/base.py,sha256=WHra9LRtlTuB1jmuNqkfVE2JUgB61Cyntn8f0b0WZg4,411
         
     | 
| 
       1609 
1616 
     | 
    
         
             
            vellum/workflows/runner/__init__.py,sha256=i1iG5sAhtpdsrlvwgH6B-m49JsINkiWyPWs8vyT-bqM,72
         
     | 
| 
       1610 
     | 
    
         
            -
            vellum/workflows/runner/runner.py,sha256= 
     | 
| 
      
 1617 
     | 
    
         
            +
            vellum/workflows/runner/runner.py,sha256=ww4fjZJBENkB5HJxdj92kTz7k_EyifCeAreupy5qIxs,31813
         
     | 
| 
       1611 
1618 
     | 
    
         
             
            vellum/workflows/sandbox.py,sha256=GVJzVjMuYzOBnSrboB0_6MMRZWBluAyQ2o7syeaeBd0,2235
         
     | 
| 
       1612 
1619 
     | 
    
         
             
            vellum/workflows/state/__init__.py,sha256=yUUdR-_Vl7UiixNDYQZ-GEM_kJI9dnOia75TtuNEsnE,60
         
     | 
| 
       1613 
1620 
     | 
    
         
             
            vellum/workflows/state/base.py,sha256=Vkhneko3VlQrPsMLU1PYSzXU_W1u7_AraJsghiv5O-4,15512
         
     | 
| 
         @@ -1643,8 +1650,8 @@ vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnad 
     | 
|
| 
       1643 
1650 
     | 
    
         
             
            vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         
     | 
| 
       1644 
1651 
     | 
    
         
             
            vellum/workflows/workflows/tests/test_base_workflow.py,sha256=tCxrV3QBHL8wfdEO3bvKteDdw32xBlUl1_WxkAwaONw,8344
         
     | 
| 
       1645 
1652 
     | 
    
         
             
            vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
         
     | 
| 
       1646 
     | 
    
         
            -
            vellum_ai-0.14. 
     | 
| 
       1647 
     | 
    
         
            -
            vellum_ai-0.14. 
     | 
| 
       1648 
     | 
    
         
            -
            vellum_ai-0.14. 
     | 
| 
       1649 
     | 
    
         
            -
            vellum_ai-0.14. 
     | 
| 
       1650 
     | 
    
         
            -
            vellum_ai-0.14. 
     | 
| 
      
 1653 
     | 
    
         
            +
            vellum_ai-0.14.28.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
         
     | 
| 
      
 1654 
     | 
    
         
            +
            vellum_ai-0.14.28.dist-info/METADATA,sha256=N7nbaIH39gbgUyBqZttgkemMWEoUpoQUJLtpd6bxTl0,5484
         
     | 
| 
      
 1655 
     | 
    
         
            +
            vellum_ai-0.14.28.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
         
     | 
| 
      
 1656 
     | 
    
         
            +
            vellum_ai-0.14.28.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
         
     | 
| 
      
 1657 
     | 
    
         
            +
            vellum_ai-0.14.28.dist-info/RECORD,,
         
     | 
| 
         @@ -94,7 +94,8 @@ class BaseInlinePromptNodeDisplay(BaseNodeVellumDisplay[_InlinePromptNodeType], 
     | 
|
| 
       94 
94 
     | 
    
         
             
                            input_name=variable_name,
         
     | 
| 
       95 
95 
     | 
    
         
             
                            value=variable_value,
         
     | 
| 
       96 
96 
     | 
    
         
             
                            display_context=display_context,
         
     | 
| 
       97 
     | 
    
         
            -
                            input_id=self.node_input_ids_by_name.get(variable_name) 
     | 
| 
      
 97 
     | 
    
         
            +
                            input_id=self.node_input_ids_by_name.get(f"{InlinePromptNode.prompt_inputs.name}.{variable_name}")
         
     | 
| 
      
 98 
     | 
    
         
            +
                            or self.node_input_ids_by_name.get(variable_name),
         
     | 
| 
       98 
99 
     | 
    
         
             
                        )
         
     | 
| 
       99 
100 
     | 
    
         
             
                        vellum_variable_type = infer_vellum_variable_type(variable_value)
         
     | 
| 
       100 
101 
     | 
    
         
             
                        node_inputs.append(node_input)
         
     | 
| 
         @@ -1,7 +1,12 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import pytest
         
     | 
| 
      
 2 
     | 
    
         
            +
            from uuid import UUID
         
     | 
| 
      
 3 
     | 
    
         
            +
            from typing import Type
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       1 
5 
     | 
    
         
             
            from vellum.workflows import BaseWorkflow
         
     | 
| 
       2 
6 
     | 
    
         
             
            from vellum.workflows.nodes import BaseNode
         
     | 
| 
       3 
7 
     | 
    
         
             
            from vellum.workflows.nodes.displayable.inline_prompt_node.node import InlinePromptNode
         
     | 
| 
       4 
8 
     | 
    
         
             
            from vellum.workflows.references.lazy import LazyReference
         
     | 
| 
      
 9 
     | 
    
         
            +
            from vellum_ee.workflows.display.nodes.vellum.inline_prompt_node import BaseInlinePromptNodeDisplay
         
     | 
| 
       5 
10 
     | 
    
         
             
            from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
         
     | 
| 
       6 
11 
     | 
    
         
             
            from vellum_ee.workflows.display.workflows.vellum_workflow_display import VellumWorkflowDisplay
         
     | 
| 
       7 
12 
     | 
    
         | 
| 
         @@ -34,7 +39,7 @@ def test_serialize_node__lazy_reference_in_prompt_inputs(): 
     | 
|
| 
       34 
39 
     | 
    
         | 
| 
       35 
40 
     | 
    
         
             
                assert lazy_reference_node["inputs"] == [
         
     | 
| 
       36 
41 
     | 
    
         
             
                    {
         
     | 
| 
       37 
     | 
    
         
            -
                        "id": " 
     | 
| 
      
 42 
     | 
    
         
            +
                        "id": "aa81c1bc-d5d8-4ae8-8946-e9f4d0c1ab5f",
         
     | 
| 
       38 
43 
     | 
    
         
             
                        "key": "attr",
         
     | 
| 
       39 
44 
     | 
    
         
             
                        "value": {
         
     | 
| 
       40 
45 
     | 
    
         
             
                            "combinator": "OR",
         
     | 
| 
         @@ -50,3 +55,77 @@ def test_serialize_node__lazy_reference_in_prompt_inputs(): 
     | 
|
| 
       50 
55 
     | 
    
         
             
                        },
         
     | 
| 
       51 
56 
     | 
    
         
             
                    }
         
     | 
| 
       52 
57 
     | 
    
         
             
                ]
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            def _no_display_class(Node: Type[InlinePromptNode]):
         
     | 
| 
      
 61 
     | 
    
         
            +
                return None
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            def _display_class_with_node_input_ids_by_name(Node: Type[InlinePromptNode]):
         
     | 
| 
      
 65 
     | 
    
         
            +
                class PromptNodeDisplay(BaseInlinePromptNodeDisplay[Node]):  # type: ignore[valid-type]
         
     | 
| 
      
 66 
     | 
    
         
            +
                    node_input_ids_by_name = {"foo": UUID("fba6a4d5-835a-4e99-afb7-f6a4aed15110")}
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                return PromptNodeDisplay
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            def _display_class_with_node_input_ids_by_name_with_inputs_prefix(Node: Type[InlinePromptNode]):
         
     | 
| 
      
 72 
     | 
    
         
            +
                class PromptNodeDisplay(BaseInlinePromptNodeDisplay[Node]):  # type: ignore[valid-type]
         
     | 
| 
      
 73 
     | 
    
         
            +
                    node_input_ids_by_name = {"prompt_inputs.foo": UUID("fba6a4d5-835a-4e99-afb7-f6a4aed15110")}
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                return PromptNodeDisplay
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            @pytest.mark.parametrize(
         
     | 
| 
      
 79 
     | 
    
         
            +
                ["GetDisplayClass", "expected_input_id"],
         
     | 
| 
      
 80 
     | 
    
         
            +
                [
         
     | 
| 
      
 81 
     | 
    
         
            +
                    (_no_display_class, "8aa4ce7f-5eb8-41b7-abd0-ea2b40c8fb88"),
         
     | 
| 
      
 82 
     | 
    
         
            +
                    (_display_class_with_node_input_ids_by_name, "fba6a4d5-835a-4e99-afb7-f6a4aed15110"),
         
     | 
| 
      
 83 
     | 
    
         
            +
                    (_display_class_with_node_input_ids_by_name_with_inputs_prefix, "fba6a4d5-835a-4e99-afb7-f6a4aed15110"),
         
     | 
| 
      
 84 
     | 
    
         
            +
                ],
         
     | 
| 
      
 85 
     | 
    
         
            +
                ids=[
         
     | 
| 
      
 86 
     | 
    
         
            +
                    "no_display_class",
         
     | 
| 
      
 87 
     | 
    
         
            +
                    "display_class_with_node_input_ids_by_name",
         
     | 
| 
      
 88 
     | 
    
         
            +
                    "display_class_with_node_input_ids_by_name_with_inputs_prefix",
         
     | 
| 
      
 89 
     | 
    
         
            +
                ],
         
     | 
| 
      
 90 
     | 
    
         
            +
            )
         
     | 
| 
      
 91 
     | 
    
         
            +
            def test_serialize_node__prompt_inputs(GetDisplayClass, expected_input_id):
         
     | 
| 
      
 92 
     | 
    
         
            +
                # GIVEN a prompt node with inputs
         
     | 
| 
      
 93 
     | 
    
         
            +
                class MyPromptNode(InlinePromptNode):
         
     | 
| 
      
 94 
     | 
    
         
            +
                    prompt_inputs = {"foo": "bar"}
         
     | 
| 
      
 95 
     | 
    
         
            +
                    blocks = []
         
     | 
| 
      
 96 
     | 
    
         
            +
                    ml_model = "gpt-4o"
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                # AND a workflow with the prompt node
         
     | 
| 
      
 99 
     | 
    
         
            +
                class Workflow(BaseWorkflow):
         
     | 
| 
      
 100 
     | 
    
         
            +
                    graph = MyPromptNode
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                # AND a display class
         
     | 
| 
      
 103 
     | 
    
         
            +
                GetDisplayClass(MyPromptNode)
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                # WHEN the workflow is serialized
         
     | 
| 
      
 106 
     | 
    
         
            +
                workflow_display = get_workflow_display(base_display_class=VellumWorkflowDisplay, workflow_class=Workflow)
         
     | 
| 
      
 107 
     | 
    
         
            +
                serialized_workflow: dict = workflow_display.serialize()
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                # THEN the node should properly serialize the inputs
         
     | 
| 
      
 110 
     | 
    
         
            +
                my_prompt_node = next(
         
     | 
| 
      
 111 
     | 
    
         
            +
                    node for node in serialized_workflow["workflow_raw_data"]["nodes"] if node["id"] == str(MyPromptNode.__id__)
         
     | 
| 
      
 112 
     | 
    
         
            +
                )
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                assert my_prompt_node["inputs"] == [
         
     | 
| 
      
 115 
     | 
    
         
            +
                    {
         
     | 
| 
      
 116 
     | 
    
         
            +
                        "id": expected_input_id,
         
     | 
| 
      
 117 
     | 
    
         
            +
                        "key": "foo",
         
     | 
| 
      
 118 
     | 
    
         
            +
                        "value": {
         
     | 
| 
      
 119 
     | 
    
         
            +
                            "rules": [
         
     | 
| 
      
 120 
     | 
    
         
            +
                                {
         
     | 
| 
      
 121 
     | 
    
         
            +
                                    "type": "CONSTANT_VALUE",
         
     | 
| 
      
 122 
     | 
    
         
            +
                                    "data": {
         
     | 
| 
      
 123 
     | 
    
         
            +
                                        "type": "STRING",
         
     | 
| 
      
 124 
     | 
    
         
            +
                                        "value": "bar",
         
     | 
| 
      
 125 
     | 
    
         
            +
                                    },
         
     | 
| 
      
 126 
     | 
    
         
            +
                                }
         
     | 
| 
      
 127 
     | 
    
         
            +
                            ],
         
     | 
| 
      
 128 
     | 
    
         
            +
                            "combinator": "OR",
         
     | 
| 
      
 129 
     | 
    
         
            +
                        },
         
     | 
| 
      
 130 
     | 
    
         
            +
                    }
         
     | 
| 
      
 131 
     | 
    
         
            +
                ]
         
     | 
| 
         @@ -1,5 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            import importlib
         
     | 
| 
      
 2 
     | 
    
         
            +
            from importlib.machinery import ModuleSpec
         
     | 
| 
       2 
3 
     | 
    
         
             
            import re
         
     | 
| 
      
 4 
     | 
    
         
            +
            import sys
         
     | 
| 
       3 
5 
     | 
    
         
             
            from typing import Optional
         
     | 
| 
       4 
6 
     | 
    
         | 
| 
       5 
7 
     | 
    
         | 
| 
         @@ -8,11 +10,20 @@ class VirtualFileLoader(importlib.abc.Loader): 
     | 
|
| 
       8 
10 
     | 
    
         
             
                    self.files = files
         
     | 
| 
       9 
11 
     | 
    
         
             
                    self.namespace = namespace
         
     | 
| 
       10 
12 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
                def create_module(self, spec):
         
     | 
| 
       12 
     | 
    
         
            -
                     
     | 
| 
      
 13 
     | 
    
         
            +
                def create_module(self, spec: ModuleSpec):
         
     | 
| 
      
 14 
     | 
    
         
            +
                    """
         
     | 
| 
      
 15 
     | 
    
         
            +
                    We started with cpython/Lib/importlib/_bootstrap.py::FrozenImporter::create_module here
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                    https://github.com/python/cpython/blob/053c285f6b41f92fbdd1d4ff0c959cceefacd7cd/Lib/importlib/_bootstrap.py#L1160C1-L1169C22
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    and reduced our needs to just updating the __file__ attribute directly.
         
     | 
| 
      
 20 
     | 
    
         
            +
                    """
         
     | 
| 
      
 21 
     | 
    
         
            +
                    module = type(sys)(spec.name)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    module.__file__ = spec.origin
         
     | 
| 
      
 23 
     | 
    
         
            +
                    return module
         
     | 
| 
       13 
24 
     | 
    
         | 
| 
       14 
25 
     | 
    
         
             
                def exec_module(self, module):
         
     | 
| 
       15 
     | 
    
         
            -
                    module_info = self._resolve_module(module.__spec__. 
     | 
| 
      
 26 
     | 
    
         
            +
                    module_info = self._resolve_module(module.__spec__.name)
         
     | 
| 
       16 
27 
     | 
    
         | 
| 
       17 
28 
     | 
    
         
             
                    if module_info:
         
     | 
| 
       18 
29 
     | 
    
         
             
                        file_path, code = module_info
         
     | 
| 
         @@ -66,7 +77,8 @@ class VirtualFileFinder(importlib.abc.MetaPathFinder, importlib.abc.Loader): 
     | 
|
| 
       66 
77 
     | 
    
         
             
                        return importlib.machinery.ModuleSpec(
         
     | 
| 
       67 
78 
     | 
    
         
             
                            fullname,
         
     | 
| 
       68 
79 
     | 
    
         
             
                            self.loader,
         
     | 
| 
       69 
     | 
    
         
            -
                            origin= 
     | 
| 
      
 80 
     | 
    
         
            +
                            origin=file_path,
         
     | 
| 
       70 
81 
     | 
    
         
             
                            is_package=is_package,
         
     | 
| 
       71 
82 
     | 
    
         
             
                        )
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
       72 
84 
     | 
    
         
             
                    return None
         
     | 
| 
         @@ -1,13 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import pytest
         
     | 
| 
       1 
2 
     | 
    
         
             
            import sys
         
     | 
| 
       2 
3 
     | 
    
         
             
            from uuid import uuid4
         
     | 
| 
       3 
4 
     | 
    
         
             
            from typing import Type, cast
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            from vellum.client.core.pydantic_utilities import UniversalBaseModel
         
     | 
| 
      
 7 
     | 
    
         
            +
            from vellum.client.types.code_executor_response import CodeExecutorResponse
         
     | 
| 
      
 8 
     | 
    
         
            +
            from vellum.client.types.number_vellum_value import NumberVellumValue
         
     | 
| 
       6 
9 
     | 
    
         
             
            from vellum.workflows import BaseWorkflow
         
     | 
| 
       7 
10 
     | 
    
         
             
            from vellum.workflows.nodes import BaseNode
         
     | 
| 
       8 
11 
     | 
    
         
             
            from vellum_ee.workflows.server.virtual_file_loader import VirtualFileFinder
         
     | 
| 
       9 
12 
     | 
    
         | 
| 
       10 
13 
     | 
    
         | 
| 
      
 14 
     | 
    
         
            +
            @pytest.fixture
         
     | 
| 
      
 15 
     | 
    
         
            +
            def mock_open(mocker):
         
     | 
| 
      
 16 
     | 
    
         
            +
                return mocker.patch("vellum.workflows.nodes.displayable.code_execution_node.utils.open")
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
       11 
19 
     | 
    
         
             
            def test_load_workflow_event_display_context():
         
     | 
| 
       12 
20 
     | 
    
         
             
                # DEPRECATED: Use `vellum.workflows.events.workflow.WorkflowEventDisplayContext` instead. Will be removed in 0.15.0
         
     | 
| 
       13 
21 
     | 
    
         
             
                from vellum_ee.workflows.display.types import WorkflowEventDisplayContext
         
     | 
| 
         @@ -69,3 +77,74 @@ class StartNode(BaseNode): 
     | 
|
| 
       69 
77 
     | 
    
         
             
                # AND the lazy reference has the correct name
         
     | 
| 
       70 
78 
     | 
    
         
             
                assert start_node.foo.instance
         
     | 
| 
       71 
79 
     | 
    
         
             
                assert start_node.foo.instance.name == "StartNode.Outputs.bar"
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            def test_load_from_module__ts_code_in_file_loader(
         
     | 
| 
      
 83 
     | 
    
         
            +
                mock_open,
         
     | 
| 
      
 84 
     | 
    
         
            +
                vellum_client,
         
     | 
| 
      
 85 
     | 
    
         
            +
            ):
         
     | 
| 
      
 86 
     | 
    
         
            +
                # GIVEN typescript code
         
     | 
| 
      
 87 
     | 
    
         
            +
                ts_code = """async function main(): any {
         
     | 
| 
      
 88 
     | 
    
         
            +
              return 5;
         
     | 
| 
      
 89 
     | 
    
         
            +
            }"""
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                # AND a workflow module with only a code execution node
         
     | 
| 
      
 92 
     | 
    
         
            +
                files = {
         
     | 
| 
      
 93 
     | 
    
         
            +
                    "__init__.py": "",
         
     | 
| 
      
 94 
     | 
    
         
            +
                    "workflow.py": """\
         
     | 
| 
      
 95 
     | 
    
         
            +
            from vellum.workflows import BaseWorkflow
         
     | 
| 
      
 96 
     | 
    
         
            +
            from .nodes.code_execution_node import CodeExecutionNode
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            class Workflow(BaseWorkflow):
         
     | 
| 
      
 99 
     | 
    
         
            +
                graph = CodeExecutionNode
         
     | 
| 
      
 100 
     | 
    
         
            +
            """,
         
     | 
| 
      
 101 
     | 
    
         
            +
                    "nodes/__init__.py": """\
         
     | 
| 
      
 102 
     | 
    
         
            +
            from .code_execution_node import CodeExecutionNode
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            __all__ = ["CodeExecutionNode"]
         
     | 
| 
      
 105 
     | 
    
         
            +
            """,
         
     | 
| 
      
 106 
     | 
    
         
            +
                    "nodes/code_execution_node.py": """\
         
     | 
| 
      
 107 
     | 
    
         
            +
            from typing import Any
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            from vellum.workflows.nodes.displayable import CodeExecutionNode as BaseCodeExecutionNode
         
     | 
| 
      
 110 
     | 
    
         
            +
            from vellum.workflows.state import BaseState
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            class CodeExecutionNode(BaseCodeExecutionNode[BaseState, int]):
         
     | 
| 
      
 113 
     | 
    
         
            +
                filepath = "./script.ts"
         
     | 
| 
      
 114 
     | 
    
         
            +
                code_inputs = {}
         
     | 
| 
      
 115 
     | 
    
         
            +
                runtime = "TYPESCRIPT_5_3_3"
         
     | 
| 
      
 116 
     | 
    
         
            +
                packages = []
         
     | 
| 
      
 117 
     | 
    
         
            +
            """,
         
     | 
| 
      
 118 
     | 
    
         
            +
                    "nodes/code_execution_node/script.ts": ts_code,
         
     | 
| 
      
 119 
     | 
    
         
            +
                }
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                namespace = str(uuid4())
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                # AND the virtual file loader is registered
         
     | 
| 
      
 124 
     | 
    
         
            +
                sys.meta_path.append(VirtualFileFinder(files, namespace))
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                # AND the open function returns our file content
         
     | 
| 
      
 127 
     | 
    
         
            +
                mock_open.return_value.__enter__.return_value.read.return_value = ts_code
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                # AND we know what the Code Execution Node will respond with
         
     | 
| 
      
 130 
     | 
    
         
            +
                mock_code_execution = CodeExecutorResponse(
         
     | 
| 
      
 131 
     | 
    
         
            +
                    log="hello",
         
     | 
| 
      
 132 
     | 
    
         
            +
                    output=NumberVellumValue(value=5),
         
     | 
| 
      
 133 
     | 
    
         
            +
                )
         
     | 
| 
      
 134 
     | 
    
         
            +
                vellum_client.execute_code.return_value = mock_code_execution
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                # WHEN the workflow is loaded
         
     | 
| 
      
 137 
     | 
    
         
            +
                Workflow = BaseWorkflow.load_from_module(namespace)
         
     | 
| 
      
 138 
     | 
    
         
            +
                workflow = Workflow()
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                # THEN the workflow is successfully initialized
         
     | 
| 
      
 141 
     | 
    
         
            +
                assert workflow
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                event = workflow.run()
         
     | 
| 
      
 144 
     | 
    
         
            +
                assert event.name == "workflow.execution.fulfilled", event.model_dump_json()
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                # AND we pass in the correct file path to the open function
         
     | 
| 
      
 147 
     | 
    
         
            +
                assert mock_open.call_args[0][0] == f"{namespace}/nodes/./script.ts"
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                # AND we invoke the Code Execution Node with the correct code
         
     | 
| 
      
 150 
     | 
    
         
            +
                assert vellum_client.execute_code.call_args.kwargs["code"] == ts_code
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     |