vellum-ai 0.14.5__py3-none-any.whl → 0.14.6__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.
Files changed (25) hide show
  1. vellum/__init__.py +6 -0
  2. vellum/client/__init__.py +8 -8
  3. vellum/client/core/client_wrapper.py +1 -1
  4. vellum/client/resources/__init__.py +2 -0
  5. vellum/client/resources/workflow_sandboxes/__init__.py +3 -0
  6. vellum/client/resources/workflow_sandboxes/client.py +146 -0
  7. vellum/client/resources/workflow_sandboxes/types/__init__.py +5 -0
  8. vellum/client/resources/workflow_sandboxes/types/list_workflow_sandbox_examples_request_tag.py +5 -0
  9. vellum/client/types/__init__.py +4 -0
  10. vellum/client/types/paginated_workflow_sandbox_example_list.py +23 -0
  11. vellum/client/types/workflow_sandbox_example.py +22 -0
  12. vellum/resources/workflow_sandboxes/types/__init__.py +3 -0
  13. vellum/resources/workflow_sandboxes/types/list_workflow_sandbox_examples_request_tag.py +3 -0
  14. vellum/types/paginated_workflow_sandbox_example_list.py +3 -0
  15. vellum/types/workflow_sandbox_example.py +3 -0
  16. vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +12 -2
  17. vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py +23 -0
  18. vellum/workflows/workflows/base.py +45 -54
  19. {vellum_ai-0.14.5.dist-info → vellum_ai-0.14.6.dist-info}/METADATA +1 -1
  20. {vellum_ai-0.14.5.dist-info → vellum_ai-0.14.6.dist-info}/RECORD +25 -17
  21. vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +31 -0
  22. vellum_ee/workflows/display/nodes/vellum/utils.py +8 -0
  23. {vellum_ai-0.14.5.dist-info → vellum_ai-0.14.6.dist-info}/LICENSE +0 -0
  24. {vellum_ai-0.14.5.dist-info → vellum_ai-0.14.6.dist-info}/WHEEL +0 -0
  25. {vellum_ai-0.14.5.dist-info → vellum_ai-0.14.6.dist-info}/entry_points.txt +0 -0
vellum/__init__.py CHANGED
@@ -259,6 +259,7 @@ from .types import (
259
259
  PaginatedTestSuiteRunExecutionList,
260
260
  PaginatedTestSuiteTestCaseList,
261
261
  PaginatedWorkflowReleaseTagReadList,
262
+ PaginatedWorkflowSandboxExampleList,
262
263
  PdfSearchResultMetaSource,
263
264
  PdfSearchResultMetaSourceRequest,
264
265
  PlainTextPromptBlock,
@@ -495,6 +496,7 @@ from .types import (
495
496
  WorkflowResultEventOutputDataNumber,
496
497
  WorkflowResultEventOutputDataSearchResults,
497
498
  WorkflowResultEventOutputDataString,
499
+ WorkflowSandboxExample,
498
500
  WorkflowStreamEvent,
499
501
  WorkspaceRead,
500
502
  WorkspaceSecretRead,
@@ -506,6 +508,7 @@ from .resources import (
506
508
  FolderEntitiesListRequestEntityStatus,
507
509
  ListDeploymentReleaseTagsRequestSource,
508
510
  ListWorkflowReleaseTagsRequestSource,
511
+ ListWorkflowSandboxExamplesRequestTag,
509
512
  WorkflowDeploymentsListRequestStatus,
510
513
  WorkflowsPullRequestFormat,
511
514
  ad_hoc,
@@ -713,6 +716,7 @@ __all__ = [
713
716
  "JsonVellumValueRequest",
714
717
  "ListDeploymentReleaseTagsRequestSource",
715
718
  "ListWorkflowReleaseTagsRequestSource",
719
+ "ListWorkflowSandboxExamplesRequestTag",
716
720
  "LogicalOperator",
717
721
  "LogprobsEnum",
718
722
  "MapNodeResult",
@@ -796,6 +800,7 @@ __all__ = [
796
800
  "PaginatedTestSuiteRunExecutionList",
797
801
  "PaginatedTestSuiteTestCaseList",
798
802
  "PaginatedWorkflowReleaseTagReadList",
803
+ "PaginatedWorkflowSandboxExampleList",
799
804
  "PdfSearchResultMetaSource",
800
805
  "PdfSearchResultMetaSourceRequest",
801
806
  "PlainTextPromptBlock",
@@ -1035,6 +1040,7 @@ __all__ = [
1035
1040
  "WorkflowResultEventOutputDataNumber",
1036
1041
  "WorkflowResultEventOutputDataSearchResults",
1037
1042
  "WorkflowResultEventOutputDataString",
1043
+ "WorkflowSandboxExample",
1038
1044
  "WorkflowStreamEvent",
1039
1045
  "WorkflowsPullRequestFormat",
1040
1046
  "WorkspaceRead",
vellum/client/__init__.py CHANGED
@@ -360,7 +360,7 @@ class Vellum:
360
360
  Optionally specify a release tag if you want to pin to a specific release of the Prompt Deployment
361
361
 
362
362
  external_id : typing.Optional[str]
363
- Optionally include a unique identifier for tracking purposes. Must be unique within a given Prompt Deployment.
363
+ Optionally include a unique identifier for tracking purposes. Must be unique within a given Workspace.
364
364
 
365
365
  expand_meta : typing.Optional[PromptDeploymentExpandMetaRequest]
366
366
  An optionally specified configuration used to opt in to including additional metadata about this prompt execution in the API response. Corresponding values will be returned under the `meta` key of the API response.
@@ -508,7 +508,7 @@ class Vellum:
508
508
  Optionally specify a release tag if you want to pin to a specific release of the Prompt Deployment
509
509
 
510
510
  external_id : typing.Optional[str]
511
- Optionally include a unique identifier for tracking purposes. Must be unique within a given Prompt Deployment.
511
+ Optionally include a unique identifier for tracking purposes. Must be unique within a given Workspace.
512
512
 
513
513
  expand_meta : typing.Optional[PromptDeploymentExpandMetaRequest]
514
514
  An optionally specified configuration used to opt in to including additional metadata about this prompt execution in the API response. Corresponding values will be returned under the `meta` key of the API response.
@@ -667,7 +667,7 @@ class Vellum:
667
667
  Optionally specify a release tag if you want to pin to a specific release of the Workflow Deployment
668
668
 
669
669
  external_id : typing.Optional[str]
670
- Optionally include a unique identifier for tracking purposes. Must be unique for a given workflow deployment.
670
+ Optionally include a unique identifier for tracking purposes. Must be unique within a given Workspace.
671
671
 
672
672
  metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
673
673
  Arbitrary JSON metadata associated with this request. Can be used to capture additional monitoring data such as user id, session id, etc. for future analysis.
@@ -794,7 +794,7 @@ class Vellum:
794
794
  Optionally specify a release tag if you want to pin to a specific release of the Workflow Deployment
795
795
 
796
796
  external_id : typing.Optional[str]
797
- Optionally include a unique identifier for tracking purposes. Must be unique for a given workflow deployment.
797
+ Optionally include a unique identifier for tracking purposes. Must be unique within a given Workspace.
798
798
 
799
799
  event_types : typing.Optional[typing.Sequence[WorkflowExecutionEventType]]
800
800
  Optionally specify which events you want to receive. Defaults to only WORKFLOW events. Note that the schema of non-WORKFLOW events is unstable and should be used with caution.
@@ -1717,7 +1717,7 @@ class AsyncVellum:
1717
1717
  Optionally specify a release tag if you want to pin to a specific release of the Prompt Deployment
1718
1718
 
1719
1719
  external_id : typing.Optional[str]
1720
- Optionally include a unique identifier for tracking purposes. Must be unique within a given Prompt Deployment.
1720
+ Optionally include a unique identifier for tracking purposes. Must be unique within a given Workspace.
1721
1721
 
1722
1722
  expand_meta : typing.Optional[PromptDeploymentExpandMetaRequest]
1723
1723
  An optionally specified configuration used to opt in to including additional metadata about this prompt execution in the API response. Corresponding values will be returned under the `meta` key of the API response.
@@ -1873,7 +1873,7 @@ class AsyncVellum:
1873
1873
  Optionally specify a release tag if you want to pin to a specific release of the Prompt Deployment
1874
1874
 
1875
1875
  external_id : typing.Optional[str]
1876
- Optionally include a unique identifier for tracking purposes. Must be unique within a given Prompt Deployment.
1876
+ Optionally include a unique identifier for tracking purposes. Must be unique within a given Workspace.
1877
1877
 
1878
1878
  expand_meta : typing.Optional[PromptDeploymentExpandMetaRequest]
1879
1879
  An optionally specified configuration used to opt in to including additional metadata about this prompt execution in the API response. Corresponding values will be returned under the `meta` key of the API response.
@@ -2040,7 +2040,7 @@ class AsyncVellum:
2040
2040
  Optionally specify a release tag if you want to pin to a specific release of the Workflow Deployment
2041
2041
 
2042
2042
  external_id : typing.Optional[str]
2043
- Optionally include a unique identifier for tracking purposes. Must be unique for a given workflow deployment.
2043
+ Optionally include a unique identifier for tracking purposes. Must be unique within a given Workspace.
2044
2044
 
2045
2045
  metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
2046
2046
  Arbitrary JSON metadata associated with this request. Can be used to capture additional monitoring data such as user id, session id, etc. for future analysis.
@@ -2175,7 +2175,7 @@ class AsyncVellum:
2175
2175
  Optionally specify a release tag if you want to pin to a specific release of the Workflow Deployment
2176
2176
 
2177
2177
  external_id : typing.Optional[str]
2178
- Optionally include a unique identifier for tracking purposes. Must be unique for a given workflow deployment.
2178
+ Optionally include a unique identifier for tracking purposes. Must be unique within a given Workspace.
2179
2179
 
2180
2180
  event_types : typing.Optional[typing.Sequence[WorkflowExecutionEventType]]
2181
2181
  Optionally specify which events you want to receive. Defaults to only WORKFLOW events. Note that the schema of non-WORKFLOW events is unstable and should be used with caution.
@@ -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.5",
21
+ "X-Fern-SDK-Version": "0.14.6",
22
22
  }
23
23
  headers["X_API_KEY"] = self.api_key
24
24
  return headers
@@ -23,6 +23,7 @@ from .deployments import DeploymentsListRequestStatus, ListDeploymentReleaseTags
23
23
  from .document_indexes import DocumentIndexesListRequestStatus
24
24
  from .folder_entities import FolderEntitiesListRequestEntityStatus
25
25
  from .workflow_deployments import ListWorkflowReleaseTagsRequestSource, WorkflowDeploymentsListRequestStatus
26
+ from .workflow_sandboxes import ListWorkflowSandboxExamplesRequestTag
26
27
  from .workflows import WorkflowsPullRequestFormat
27
28
 
28
29
  __all__ = [
@@ -31,6 +32,7 @@ __all__ = [
31
32
  "FolderEntitiesListRequestEntityStatus",
32
33
  "ListDeploymentReleaseTagsRequestSource",
33
34
  "ListWorkflowReleaseTagsRequestSource",
35
+ "ListWorkflowSandboxExamplesRequestTag",
34
36
  "WorkflowDeploymentsListRequestStatus",
35
37
  "WorkflowsPullRequestFormat",
36
38
  "ad_hoc",
@@ -1,2 +1,5 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ from .types import ListWorkflowSandboxExamplesRequestTag
4
+
5
+ __all__ = ["ListWorkflowSandboxExamplesRequestTag"]
@@ -8,6 +8,8 @@ from ...core.jsonable_encoder import jsonable_encoder
8
8
  from ...core.pydantic_utilities import parse_obj_as
9
9
  from json.decoder import JSONDecodeError
10
10
  from ...core.api_error import ApiError
11
+ from .types.list_workflow_sandbox_examples_request_tag import ListWorkflowSandboxExamplesRequestTag
12
+ from ...types.paginated_workflow_sandbox_example_list import PaginatedWorkflowSandboxExampleList
11
13
  from ...core.client_wrapper import AsyncClientWrapper
12
14
 
13
15
  # this is used as the default value for optional parameters
@@ -97,6 +99,74 @@ class WorkflowSandboxesClient:
97
99
  raise ApiError(status_code=_response.status_code, body=_response.text)
98
100
  raise ApiError(status_code=_response.status_code, body=_response_json)
99
101
 
102
+ def list_workflow_sandbox_examples(
103
+ self,
104
+ *,
105
+ limit: typing.Optional[int] = None,
106
+ offset: typing.Optional[int] = None,
107
+ ordering: typing.Optional[str] = None,
108
+ tag: typing.Optional[ListWorkflowSandboxExamplesRequestTag] = None,
109
+ request_options: typing.Optional[RequestOptions] = None,
110
+ ) -> PaginatedWorkflowSandboxExampleList:
111
+ """
112
+ List Workflow Sandbox examples that were previously cloned into the User's Workspace
113
+
114
+ Parameters
115
+ ----------
116
+ limit : typing.Optional[int]
117
+ Number of results to return per page.
118
+
119
+ offset : typing.Optional[int]
120
+ The initial index from which to return the results.
121
+
122
+ ordering : typing.Optional[str]
123
+ Which field to use when ordering the results.
124
+
125
+ tag : typing.Optional[ListWorkflowSandboxExamplesRequestTag]
126
+
127
+ request_options : typing.Optional[RequestOptions]
128
+ Request-specific configuration.
129
+
130
+ Returns
131
+ -------
132
+ PaginatedWorkflowSandboxExampleList
133
+
134
+
135
+ Examples
136
+ --------
137
+ from vellum import Vellum
138
+
139
+ client = Vellum(
140
+ api_key="YOUR_API_KEY",
141
+ )
142
+ client.workflow_sandboxes.list_workflow_sandbox_examples()
143
+ """
144
+ _response = self._client_wrapper.httpx_client.request(
145
+ "v1/workflow-sandboxes/examples",
146
+ base_url=self._client_wrapper.get_environment().default,
147
+ method="GET",
148
+ params={
149
+ "limit": limit,
150
+ "offset": offset,
151
+ "ordering": ordering,
152
+ "tag": tag,
153
+ },
154
+ request_options=request_options,
155
+ )
156
+ try:
157
+ if 200 <= _response.status_code < 300:
158
+ return typing.cast(
159
+ PaginatedWorkflowSandboxExampleList,
160
+ parse_obj_as(
161
+ type_=PaginatedWorkflowSandboxExampleList, # type: ignore
162
+ object_=_response.json(),
163
+ ),
164
+ )
165
+ _response_json = _response.json()
166
+ except JSONDecodeError:
167
+ raise ApiError(status_code=_response.status_code, body=_response.text)
168
+ raise ApiError(status_code=_response.status_code, body=_response_json)
169
+
100
170
 
101
171
  class AsyncWorkflowSandboxesClient:
102
172
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -188,3 +258,79 @@ class AsyncWorkflowSandboxesClient:
188
258
  except JSONDecodeError:
189
259
  raise ApiError(status_code=_response.status_code, body=_response.text)
190
260
  raise ApiError(status_code=_response.status_code, body=_response_json)
261
+
262
+ async def list_workflow_sandbox_examples(
263
+ self,
264
+ *,
265
+ limit: typing.Optional[int] = None,
266
+ offset: typing.Optional[int] = None,
267
+ ordering: typing.Optional[str] = None,
268
+ tag: typing.Optional[ListWorkflowSandboxExamplesRequestTag] = None,
269
+ request_options: typing.Optional[RequestOptions] = None,
270
+ ) -> PaginatedWorkflowSandboxExampleList:
271
+ """
272
+ List Workflow Sandbox examples that were previously cloned into the User's Workspace
273
+
274
+ Parameters
275
+ ----------
276
+ limit : typing.Optional[int]
277
+ Number of results to return per page.
278
+
279
+ offset : typing.Optional[int]
280
+ The initial index from which to return the results.
281
+
282
+ ordering : typing.Optional[str]
283
+ Which field to use when ordering the results.
284
+
285
+ tag : typing.Optional[ListWorkflowSandboxExamplesRequestTag]
286
+
287
+ request_options : typing.Optional[RequestOptions]
288
+ Request-specific configuration.
289
+
290
+ Returns
291
+ -------
292
+ PaginatedWorkflowSandboxExampleList
293
+
294
+
295
+ Examples
296
+ --------
297
+ import asyncio
298
+
299
+ from vellum import AsyncVellum
300
+
301
+ client = AsyncVellum(
302
+ api_key="YOUR_API_KEY",
303
+ )
304
+
305
+
306
+ async def main() -> None:
307
+ await client.workflow_sandboxes.list_workflow_sandbox_examples()
308
+
309
+
310
+ asyncio.run(main())
311
+ """
312
+ _response = await self._client_wrapper.httpx_client.request(
313
+ "v1/workflow-sandboxes/examples",
314
+ base_url=self._client_wrapper.get_environment().default,
315
+ method="GET",
316
+ params={
317
+ "limit": limit,
318
+ "offset": offset,
319
+ "ordering": ordering,
320
+ "tag": tag,
321
+ },
322
+ request_options=request_options,
323
+ )
324
+ try:
325
+ if 200 <= _response.status_code < 300:
326
+ return typing.cast(
327
+ PaginatedWorkflowSandboxExampleList,
328
+ parse_obj_as(
329
+ type_=PaginatedWorkflowSandboxExampleList, # type: ignore
330
+ object_=_response.json(),
331
+ ),
332
+ )
333
+ _response_json = _response.json()
334
+ except JSONDecodeError:
335
+ raise ApiError(status_code=_response.status_code, body=_response.text)
336
+ raise ApiError(status_code=_response.status_code, body=_response_json)
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from .list_workflow_sandbox_examples_request_tag import ListWorkflowSandboxExamplesRequestTag
4
+
5
+ __all__ = ["ListWorkflowSandboxExamplesRequestTag"]
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ ListWorkflowSandboxExamplesRequestTag = typing.Union[typing.Literal["ONBOARDING", "TEMPLATES"], typing.Any]
@@ -267,6 +267,7 @@ from .paginated_slim_workflow_deployment_list import PaginatedSlimWorkflowDeploy
267
267
  from .paginated_test_suite_run_execution_list import PaginatedTestSuiteRunExecutionList
268
268
  from .paginated_test_suite_test_case_list import PaginatedTestSuiteTestCaseList
269
269
  from .paginated_workflow_release_tag_read_list import PaginatedWorkflowReleaseTagReadList
270
+ from .paginated_workflow_sandbox_example_list import PaginatedWorkflowSandboxExampleList
270
271
  from .pdf_search_result_meta_source import PdfSearchResultMetaSource
271
272
  from .pdf_search_result_meta_source_request import PdfSearchResultMetaSourceRequest
272
273
  from .plain_text_prompt_block import PlainTextPromptBlock
@@ -519,6 +520,7 @@ from .workflow_result_event_output_data_json import WorkflowResultEventOutputDat
519
520
  from .workflow_result_event_output_data_number import WorkflowResultEventOutputDataNumber
520
521
  from .workflow_result_event_output_data_search_results import WorkflowResultEventOutputDataSearchResults
521
522
  from .workflow_result_event_output_data_string import WorkflowResultEventOutputDataString
523
+ from .workflow_sandbox_example import WorkflowSandboxExample
522
524
  from .workflow_stream_event import WorkflowStreamEvent
523
525
  from .workspace_read import WorkspaceRead
524
526
  from .workspace_secret_read import WorkspaceSecretRead
@@ -779,6 +781,7 @@ __all__ = [
779
781
  "PaginatedTestSuiteRunExecutionList",
780
782
  "PaginatedTestSuiteTestCaseList",
781
783
  "PaginatedWorkflowReleaseTagReadList",
784
+ "PaginatedWorkflowSandboxExampleList",
782
785
  "PdfSearchResultMetaSource",
783
786
  "PdfSearchResultMetaSourceRequest",
784
787
  "PlainTextPromptBlock",
@@ -1015,6 +1018,7 @@ __all__ = [
1015
1018
  "WorkflowResultEventOutputDataNumber",
1016
1019
  "WorkflowResultEventOutputDataSearchResults",
1017
1020
  "WorkflowResultEventOutputDataString",
1021
+ "WorkflowSandboxExample",
1018
1022
  "WorkflowStreamEvent",
1019
1023
  "WorkspaceRead",
1020
1024
  "WorkspaceSecretRead",
@@ -0,0 +1,23 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.pydantic_utilities import UniversalBaseModel
4
+ import typing
5
+ from .workflow_sandbox_example import WorkflowSandboxExample
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
+ import pydantic
8
+
9
+
10
+ class PaginatedWorkflowSandboxExampleList(UniversalBaseModel):
11
+ count: typing.Optional[int] = None
12
+ next: typing.Optional[str] = None
13
+ previous: typing.Optional[str] = None
14
+ results: typing.Optional[typing.List[WorkflowSandboxExample]] = None
15
+
16
+ if IS_PYDANTIC_V2:
17
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
18
+ else:
19
+
20
+ class Config:
21
+ frozen = True
22
+ smart_union = True
23
+ extra = pydantic.Extra.allow
@@ -0,0 +1,22 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.pydantic_utilities import UniversalBaseModel
4
+ import typing
5
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
6
+ import pydantic
7
+
8
+
9
+ class WorkflowSandboxExample(UniversalBaseModel):
10
+ id: str
11
+ label: str
12
+ description: typing.Optional[str] = None
13
+ icon_name: typing.Optional[str] = None
14
+
15
+ if IS_PYDANTIC_V2:
16
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
17
+ else:
18
+
19
+ class Config:
20
+ frozen = True
21
+ smart_union = True
22
+ extra = pydantic.Extra.allow
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.resources.workflow_sandboxes.types import *
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.resources.workflow_sandboxes.types.list_workflow_sandbox_examples_request_tag import *
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.paginated_workflow_sandbox_example_list import *
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.workflow_sandbox_example import *
@@ -127,10 +127,20 @@ class SubworkflowDeploymentNode(BaseNode[StateType], Generic[StateType]):
127
127
  "execution_context": {"parent_context": parent_context},
128
128
  **request_options.get("additional_body_parameters", {}),
129
129
  }
130
+
131
+ try:
132
+ deployment_id = str(self.deployment) if isinstance(self.deployment, UUID) else None
133
+ deployment_name = self.deployment if isinstance(self.deployment, str) else None
134
+ except AttributeError:
135
+ raise NodeException(
136
+ code=WorkflowErrorCode.NODE_EXECUTION,
137
+ message="Expected subworkflow deployment attribute to be either a UUID or STR, got None instead",
138
+ )
139
+
130
140
  subworkflow_stream = self._context.vellum_client.execute_workflow_stream(
131
141
  inputs=self._compile_subworkflow_inputs(),
132
- workflow_deployment_id=str(self.deployment) if isinstance(self.deployment, UUID) else None,
133
- workflow_deployment_name=self.deployment if isinstance(self.deployment, str) else None,
142
+ workflow_deployment_id=deployment_id,
143
+ workflow_deployment_name=deployment_name,
134
144
  release_tag=self.release_tag,
135
145
  external_id=self.external_id,
136
146
  event_types=["WORKFLOW"],
@@ -11,6 +11,8 @@ from vellum.client.types.workflow_request_chat_history_input_request import Work
11
11
  from vellum.client.types.workflow_request_json_input_request import WorkflowRequestJsonInputRequest
12
12
  from vellum.client.types.workflow_result_event import WorkflowResultEvent
13
13
  from vellum.client.types.workflow_stream_event import WorkflowStreamEvent
14
+ from vellum.workflows.errors import WorkflowErrorCode
15
+ from vellum.workflows.exceptions import NodeException
14
16
  from vellum.workflows.nodes.displayable.subworkflow_deployment_node.node import SubworkflowDeploymentNode
15
17
 
16
18
 
@@ -129,3 +131,24 @@ def test_run_workflow__any_array(vellum_client):
129
131
  assert call_kwargs["inputs"] == [
130
132
  WorkflowRequestJsonInputRequest(name="fruits", value=["apple", "banana", "cherry"]),
131
133
  ]
134
+
135
+
136
+ def test_run_workflow__no_deployment():
137
+ """Confirm that we raise error when running a subworkflow deployment node with no deployment attribute set"""
138
+
139
+ # GIVEN a Subworkflow Deployment Node
140
+ class ExampleSubworkflowDeploymentNode(SubworkflowDeploymentNode):
141
+ subworkflow_inputs = {
142
+ "fruits": ["apple", "banana", "cherry"],
143
+ }
144
+
145
+ # WHEN/THEN running the node should raise a NodeException
146
+ node = ExampleSubworkflowDeploymentNode()
147
+ with pytest.raises(NodeException) as exc_info:
148
+ list(node.run())
149
+
150
+ # AND the error message should be correct
151
+ assert exc_info.value.code == WorkflowErrorCode.NODE_EXECUTION
152
+ assert "Expected subworkflow deployment attribute to be either a UUID or STR, got None instead" in str(
153
+ exc_info.value
154
+ )
@@ -178,48 +178,64 @@ class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
178
178
  def context(self) -> WorkflowContext:
179
179
  return self._context
180
180
 
181
- @classmethod
182
- def get_subgraphs(cls) -> List[Graph]:
183
- original_graph = cls.graph
184
- if isinstance(original_graph, Graph):
185
- return [original_graph]
186
- if isinstance(original_graph, set):
187
- return [
188
- subgraph if isinstance(subgraph, Graph) else Graph.from_node(subgraph) for subgraph in original_graph
189
- ]
190
- if issubclass(original_graph, BaseNode):
191
- return [Graph.from_node(original_graph)]
192
-
193
- raise ValueError(f"Unexpected graph type: {original_graph.__class__}")
194
-
195
- @classmethod
196
- def get_edges(cls) -> Iterator[Edge]:
181
+ @staticmethod
182
+ def _resolve_graph(graph: GraphAttribute) -> List[Graph]:
197
183
  """
198
- Returns an iterator over the edges in the workflow. We use a set to
199
- ensure uniqueness, and the iterator to preserve order.
184
+ Resolves a single graph source to a list of Graph objects.
200
185
  """
186
+ if isinstance(graph, Graph):
187
+ return [graph]
188
+ if isinstance(graph, set):
189
+ graphs = []
190
+ for item in graph:
191
+ if isinstance(item, Graph):
192
+ graphs.append(item)
193
+ elif issubclass(item, BaseNode):
194
+ graphs.append(Graph.from_node(item))
195
+ else:
196
+ raise ValueError(f"Unexpected graph type: {type(item)}")
197
+ return graphs
198
+ if issubclass(graph, BaseNode):
199
+ return [Graph.from_node(graph)]
200
+ raise ValueError(f"Unexpected graph type: {type(graph)}")
201
201
 
202
+ @staticmethod
203
+ def _get_edges_from_subgraphs(subgraphs: Iterable[Graph]) -> Iterator[Edge]:
202
204
  edges = set()
203
- subgraphs = cls.get_subgraphs()
204
205
  for subgraph in subgraphs:
205
206
  for edge in subgraph.edges:
206
207
  if edge not in edges:
207
208
  edges.add(edge)
208
209
  yield edge
209
210
 
211
+ @staticmethod
212
+ def _get_nodes_from_subgraphs(subgraphs: Iterable[Graph]) -> Iterator[Type[BaseNode]]:
213
+ nodes = set()
214
+ for subgraph in subgraphs:
215
+ for node in subgraph.nodes:
216
+ if node not in nodes:
217
+ nodes.add(node)
218
+ yield node
219
+
220
+ @classmethod
221
+ def get_subgraphs(cls) -> List[Graph]:
222
+ return cls._resolve_graph(cls.graph)
223
+
224
+ @classmethod
225
+ def get_edges(cls) -> Iterator[Edge]:
226
+ """
227
+ Returns an iterator over the edges in the workflow. We use a set to
228
+ ensure uniqueness, and the iterator to preserve order.
229
+ """
230
+ return cls._get_edges_from_subgraphs(cls.get_subgraphs())
231
+
210
232
  @classmethod
211
233
  def get_nodes(cls) -> Iterator[Type[BaseNode]]:
212
234
  """
213
235
  Returns an iterator over the nodes in the workflow. We use a set to
214
236
  ensure uniqueness, and the iterator to preserve order.
215
237
  """
216
-
217
- nodes = set()
218
- for subgraph in cls.get_subgraphs():
219
- for node in subgraph.nodes:
220
- if node not in nodes:
221
- nodes.add(node)
222
- yield node
238
+ return cls._get_nodes_from_subgraphs(cls.get_subgraphs())
223
239
 
224
240
  @classmethod
225
241
  def get_unused_subgraphs(cls) -> List[Graph]:
@@ -228,19 +244,9 @@ class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
228
244
  """
229
245
  if not hasattr(cls, "unused_graphs"):
230
246
  return []
231
-
232
247
  graphs = []
233
248
  for item in cls.unused_graphs:
234
- if isinstance(item, Graph):
235
- graphs.append(item)
236
- elif isinstance(item, set):
237
- for subitem in item:
238
- if isinstance(subitem, Graph):
239
- graphs.append(subitem)
240
- elif issubclass(subitem, BaseNode):
241
- graphs.append(Graph.from_node(subitem))
242
- elif issubclass(item, BaseNode):
243
- graphs.append(Graph.from_node(item))
249
+ graphs.extend(cls._resolve_graph(item))
244
250
  return graphs
245
251
 
246
252
  @classmethod
@@ -248,29 +254,14 @@ class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
248
254
  """
249
255
  Returns an iterator over the nodes that are defined but not used in the graph.
250
256
  """
251
- if not hasattr(cls, "unused_graphs"):
252
- yield from ()
253
- else:
254
- nodes = set()
255
- subgraphs = cls.get_unused_subgraphs()
256
- for subgraph in subgraphs:
257
- for node in subgraph.nodes:
258
- if node not in nodes:
259
- nodes.add(node)
260
- yield node
257
+ return cls._get_nodes_from_subgraphs(cls.get_unused_subgraphs())
261
258
 
262
259
  @classmethod
263
260
  def get_unused_edges(cls) -> Iterator[Edge]:
264
261
  """
265
262
  Returns an iterator over edges that are defined but not used in the graph.
266
263
  """
267
- edges = set()
268
- subgraphs = cls.get_unused_subgraphs()
269
- for subgraph in subgraphs:
270
- for edge in subgraph.edges:
271
- if edge not in edges:
272
- edges.add(edge)
273
- yield edge
264
+ return cls._get_edges_from_subgraphs(cls.get_unused_subgraphs())
274
265
 
275
266
  @classmethod
276
267
  def get_entrypoints(cls) -> Iterable[Type[BaseNode]]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.14.5
3
+ Version: 0.14.6
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -50,9 +50,9 @@ vellum_ee/workflows/display/nodes/vellum/tests/__init__.py,sha256=47DEQpj8HBSa-_
50
50
  vellum_ee/workflows/display/nodes/vellum/tests/test_error_node.py,sha256=ulrpoYUW-5kIxfG4Lf5F2p0k_EoYKhmahEbF3P_eruM,1648
51
51
  vellum_ee/workflows/display/nodes/vellum/tests/test_prompt_node.py,sha256=bg9INsXiWfyK047u8TD1oEOFYrqDq8GC7Hvgz69n7BE,1988
52
52
  vellum_ee/workflows/display/nodes/vellum/tests/test_try_node.py,sha256=mtzB8LJlFCHVFM4H5AanLp29gQfaVmnN4A4iaRGJHoI,2427
53
- vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py,sha256=3uT7Gbc0f_mQ3u8uZuCWd0mJ4GtWbz2gbUMySYaVlNE,3774
53
+ vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py,sha256=4YUaTeD_OWF-UaPMyOTBTu9skGC1jgSHlAYrzbH7Z04,5039
54
54
  vellum_ee/workflows/display/nodes/vellum/try_node.py,sha256=HBfGz4yt9GlmMW9JxzaCacPnHBDNIeXE8Jhqr9DqLLw,6191
55
- vellum_ee/workflows/display/nodes/vellum/utils.py,sha256=OEGHjQSbuUgJexXI1aubYW33z2F_YdkhQ8REahfz864,4320
55
+ vellum_ee/workflows/display/nodes/vellum/utils.py,sha256=F_0BrlSszllK_BhryPbojIleLq2dGXOfQD1rVp3fNFg,4733
56
56
  vellum_ee/workflows/display/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
57
  vellum_ee/workflows/display/tests/test_vellum_workflow_display.py,sha256=1EEvkKQRfOKlnpLxE9-hKSsVLLaelM39LY7007LM5dg,4983
58
58
  vellum_ee/workflows/display/tests/workflow_serialization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -115,12 +115,12 @@ vellum_ee/workflows/tests/local_workflow/workflow.py,sha256=A4qOzOPNwePYxWbcAgIP
115
115
  vellum_ee/workflows/tests/test_display_meta.py,sha256=pzdqND4KLWs7EUIbpXuqgso7BIRpoUsO3T_bgeENs0Q,2205
116
116
  vellum_ee/workflows/tests/test_server.py,sha256=SvKUrUPmOf3sIInXcFjETekql60npb4cAn1GPbF0bPs,391
117
117
  vellum_ee/workflows/tests/test_virtual_files.py,sha256=TJEcMR0v2S8CkloXNmCHA0QW0K6pYNGaIjraJz7sFvY,2762
118
- vellum/__init__.py,sha256=NPSLAe9-b6SSiyf-FrvMxVy-cKsAEerg8m_HhINTqmE,35794
118
+ vellum/__init__.py,sha256=BGZ28ICgCMzo3Qjj3IN3eMsvylstMCl9C1YKzrQNRnk,36024
119
119
  vellum/client/README.md,sha256=JkCJjmMZl4jrPj46pkmL9dpK4gSzQQmP5I7z4aME4LY,4749
120
- vellum/client/__init__.py,sha256=j6zi0NZ4BMC6JrwckvzMWuG5x8KoOvO4KqsLhvVCa68,117624
120
+ vellum/client/__init__.py,sha256=tKtdM1_GqmGq1gpi9ydWD_T-MM7fPn8QdHh8ww19cNI,117564
121
121
  vellum/client/core/__init__.py,sha256=SQ85PF84B9MuKnBwHNHWemSGuy-g_515gFYNFhvEE0I,1438
122
122
  vellum/client/core/api_error.py,sha256=RE8LELok2QCjABadECTvtDp7qejA1VmINCh6TbqPwSE,426
123
- vellum/client/core/client_wrapper.py,sha256=XW9zEBd9XlCTI0wEOgZ6LI4dCsGwvpW4NO7KogWDgao,1868
123
+ vellum/client/core/client_wrapper.py,sha256=Hye69mrkKpKvBVFEfZKH3c08doQVIZ0VGlBRZZmgr0k,1868
124
124
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
125
125
  vellum/client/core/file.py,sha256=X9IbmkZmB2bB_DpmZAO3crWdXagOakAyn6UCOCImCPg,2322
126
126
  vellum/client/core/http_client.py,sha256=R0pQpCppnEtxccGvXl4uJ76s7ro_65Fo_erlNNLp_AI,19228
@@ -136,7 +136,7 @@ vellum/client/errors/bad_request_error.py,sha256=_EbO8mWqN9kFZPvIap8qa1lL_EWkRcs
136
136
  vellum/client/errors/forbidden_error.py,sha256=QO1kKlhClAPES6zsEK7g9pglWnxn3KWaOCAawWOg6Aw,263
137
137
  vellum/client/errors/internal_server_error.py,sha256=8USCagXyJJ1MOm9snpcXIUt6eNXvrd_aq7Gfcu1vlOI,268
138
138
  vellum/client/errors/not_found_error.py,sha256=tBVCeBC8n3C811WHRj_n-hs3h8MqwR5gp0vLiobk7W8,262
139
- vellum/client/resources/__init__.py,sha256=j-SQQ4yYDgxbT8MdAhz7BePlsQOX7uvbWM9mluf1FWs,1452
139
+ vellum/client/resources/__init__.py,sha256=g95miLphTYIegm6D-G3sWk-Sf0-5EulFpMGNJMxpp1Y,1567
140
140
  vellum/client/resources/ad_hoc/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
141
141
  vellum/client/resources/ad_hoc/client.py,sha256=_liorv4AsoJ55kVu0a5oWB3Qeff0iUKXqoHEIyDWLxc,14173
142
142
  vellum/client/resources/container_images/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
@@ -173,8 +173,10 @@ vellum/client/resources/workflow_deployments/client.py,sha256=H9MhGYZVx1WLHE5j83
173
173
  vellum/client/resources/workflow_deployments/types/__init__.py,sha256=W7DKJ1nduwhRckYLvH7wHLdaGH9MXHTZkxwG7FdTngY,340
174
174
  vellum/client/resources/workflow_deployments/types/list_workflow_release_tags_request_source.py,sha256=LPETHLX9Ygha_JRT9oWZAZR6clv-W1tTelXzktkTBX8,178
175
175
  vellum/client/resources/workflow_deployments/types/workflow_deployments_list_request_status.py,sha256=FXVkVmGM6DZ2RpTGnZXWJYiVlLQ-K5fDtX3WMaBPaWk,182
176
- vellum/client/resources/workflow_sandboxes/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
177
- vellum/client/resources/workflow_sandboxes/client.py,sha256=3wVQxkjrJ5bIS8fB5FpKXCP2dX38299ghWrJ8YmXxwQ,7435
176
+ vellum/client/resources/workflow_sandboxes/__init__.py,sha256=OR3wE3pTgsZlTS-0ukeMWzSuEZF8PszuQTCHDh6JybI,175
177
+ vellum/client/resources/workflow_sandboxes/client.py,sha256=4FfB7DCAo8DDd3CDlmRiycMjnZhP4oWEbfGuhtzVfwo,12404
178
+ vellum/client/resources/workflow_sandboxes/types/__init__.py,sha256=EaGVRU1w6kJiiHrbZOeEa0c3ggjfgv_jBqsyOkCRWOI,212
179
+ vellum/client/resources/workflow_sandboxes/types/list_workflow_sandbox_examples_request_tag.py,sha256=TEwWit20W3X-zWPPLAhmUG05UudG9gaBSJ4Q4-rNJws,188
178
180
  vellum/client/resources/workflows/__init__.py,sha256=Z4xi8Nxd9U4t35FQSepTt1p-ns0X1xtdNs168kUcuBk,153
179
181
  vellum/client/resources/workflows/client.py,sha256=hM7FDn05XHhQk599ti8CI4moIg0RVoEFil3Wp9v9UZk,11215
180
182
  vellum/client/resources/workflows/types/__init__.py,sha256=-uFca4ypncAOvfsg6sjD-5C9zWdA5qNvU6m675GphVg,177
@@ -183,7 +185,7 @@ vellum/client/resources/workspace_secrets/__init__.py,sha256=FTtvy8EDg9nNNg9WCat
183
185
  vellum/client/resources/workspace_secrets/client.py,sha256=h7UzXLyTttPq1t-JZGMg1BWxypxJvBGUdqg7KGT7MK4,8027
184
186
  vellum/client/resources/workspaces/__init__.py,sha256=FTtvy8EDg9nNNg9WCatVgKTRYV8-_v1roeGPAKoa_pw,65
185
187
  vellum/client/resources/workspaces/client.py,sha256=RthwzN1o-Jxwg5yyNNodavFyNUSxfLoTv26w3mRR5g8,3595
186
- vellum/client/types/__init__.py,sha256=HsQa33k5NOOW9zQdCCxp6REWnFHvqqR-vJl0RlNmxh0,53975
188
+ vellum/client/types/__init__.py,sha256=w4LPPCUDsYhlZyPcoN7B3cCwPDL87A-UIlYTtiO0zO4,54198
187
189
  vellum/client/types/ad_hoc_execute_prompt_event.py,sha256=bCjujA2XsOgyF3bRZbcEqV2rOIymRgsLoIRtZpB14xg,607
188
190
  vellum/client/types/ad_hoc_expand_meta.py,sha256=1gv-NCsy_6xBYupLvZH979yf2VMdxAU-l0y0ynMKZaw,1331
189
191
  vellum/client/types/ad_hoc_fulfilled_prompt_execution_meta.py,sha256=Bfvf1d_dkmshxRACVM5vcxbH_7AQY23RmrrnPc0ytYY,939
@@ -439,6 +441,7 @@ vellum/client/types/paginated_slim_workflow_deployment_list.py,sha256=b0SGPewaOK
439
441
  vellum/client/types/paginated_test_suite_run_execution_list.py,sha256=_NCKlKzs-8h0oZFhbGLO4sMt3xh9jicPqJdYu-NN-8c,1019
440
442
  vellum/client/types/paginated_test_suite_test_case_list.py,sha256=9KrCCQKy0egMmVx5U2k6o1GjNrUYpVvGG_hm2cHqIzc,995
441
443
  vellum/client/types/paginated_workflow_release_tag_read_list.py,sha256=dH24ESWyAMVtyHsBkxG8kJ9oORY04Wn3IN-7jvV7Lu4,818
444
+ vellum/client/types/paginated_workflow_sandbox_example_list.py,sha256=rCivuKp5fzVV8PdRwyiet7bEmLxX_1hv8N0vn0xaT70,817
442
445
  vellum/client/types/pdf_search_result_meta_source.py,sha256=EMVhqdN1bwE6Ujdx4VhlmKQtJvitN-57kY8oZPxh9dI,1126
443
446
  vellum/client/types/pdf_search_result_meta_source_request.py,sha256=nUhaD2Kw1paGC6O_ICVNu3R0e1SVgTshRTkGNgmcjXo,1133
444
447
  vellum/client/types/plain_text_prompt_block.py,sha256=cqEN-B4mcvMw_9lBN7FQG8pk9b5LBJ9xpM6PTgkGiqs,930
@@ -675,6 +678,7 @@ vellum/client/types/workflow_result_event_output_data_json.py,sha256=8MrgcTSVUby
675
678
  vellum/client/types/workflow_result_event_output_data_number.py,sha256=OZYYUF3ayq7gyaesRK3YRaTMVgxFdeFGtOpTPWX10yk,1081
676
679
  vellum/client/types/workflow_result_event_output_data_search_results.py,sha256=U34IK7ZvBG70ZBO4SEqbaNzIrV9Zn1NXabNh3M9v_hg,1172
677
680
  vellum/client/types/workflow_result_event_output_data_string.py,sha256=tM3kgh6tEhD0dFEb_7UU0-UspeN4pUdINCcCrD64W74,1228
681
+ vellum/client/types/workflow_sandbox_example.py,sha256=ZYFI7ZahyRYMNVmF8LZcF-_lkhqt95WiWXT6SpxnFHk,666
678
682
  vellum/client/types/workflow_stream_event.py,sha256=Wn3Yzuy9MqWAeo8tEaXDTKDEbJoA8DdYdMVq8EKuhu8,361
679
683
  vellum/client/types/workspace_read.py,sha256=ocPtWvOwadqkU3z21bJgE4JeLYTAkOqBlKkc9lDDFFg,697
680
684
  vellum/client/types/workspace_secret_read.py,sha256=3CnHDG72IAY0KRNvc31F0xLmhnpwjQHnDYCfQJzCxI0,714
@@ -755,6 +759,8 @@ vellum/resources/workflow_deployments/types/list_workflow_release_tags_request_s
755
759
  vellum/resources/workflow_deployments/types/workflow_deployments_list_request_status.py,sha256=mLfHzwK3uBQfw8nku6YmceHoaWksRPRZzpNBy9MGBv4,209
756
760
  vellum/resources/workflow_sandboxes/__init__.py,sha256=jHqdk62iizWsMzrhlXMhAON5eX4CRgL7ipux4MqoK2Y,160
757
761
  vellum/resources/workflow_sandboxes/client.py,sha256=6hUU770XG4lOoZZOwvAqmUz5XZDgRd3MPWZs1wieWEM,167
762
+ vellum/resources/workflow_sandboxes/types/__init__.py,sha256=jMwkDLd5Xc4hheGoU-h087t1L3qxp4llmT6MG5MeufA,166
763
+ vellum/resources/workflow_sandboxes/types/list_workflow_sandbox_examples_request_tag.py,sha256=ylKYQDob7ivDO05K9Y21qfAYQmWvsuhu25C6CKjby5c,209
758
764
  vellum/resources/workflows/__init__.py,sha256=NhC5vYlg2Jre4lekOubbziseG5_k2c9-tlxGJ2zNVHU,151
759
765
  vellum/resources/workflows/client.py,sha256=HVVkYDhHnodVD-MAj1oABf4PGVHr4XNGJrMnShuX-Oc,158
760
766
  vellum/resources/workflows/types/__init__.py,sha256=n3dH29XbL5XgAZesnDu2WVWUd_JqPU-s1vOKU_56oDs,157
@@ -1019,6 +1025,7 @@ vellum/types/paginated_slim_workflow_deployment_list.py,sha256=3QgvxRFqcOw9z-cl0
1019
1025
  vellum/types/paginated_test_suite_run_execution_list.py,sha256=XEr928_4w9Rw9_q6dshxPWfXXptLdRlDp-frKIIcdYQ,177
1020
1026
  vellum/types/paginated_test_suite_test_case_list.py,sha256=LoyXDEr2yXrkniJ25HctBWvhqKQ987XItukUwPYUIhQ,173
1021
1027
  vellum/types/paginated_workflow_release_tag_read_list.py,sha256=XUeQn_6JPJ6K2qts-NZIEEZF94C3U2AosStc2k57eWY,178
1028
+ vellum/types/paginated_workflow_sandbox_example_list.py,sha256=FlPNK6QtzQL9yD-k_qpQrE8yMARrJRjk5aGf6ZTbGyY,177
1022
1029
  vellum/types/pdf_search_result_meta_source.py,sha256=tkM53z99Zky8ifkcfj1HoS7k-scjy6xeVInVDjMTBzM,167
1023
1030
  vellum/types/pdf_search_result_meta_source_request.py,sha256=TW9FWTdqZi-SuERKkjMdrKBgQEq3RA4W9nwefm8it6k,175
1024
1031
  vellum/types/plain_text_prompt_block.py,sha256=K5tGXMDCVTLDIDOL17TjLvZD6pMaHnRtcSYfXOrzQMM,161
@@ -1255,6 +1262,7 @@ vellum/types/workflow_result_event_output_data_json.py,sha256=z5uMkd759__fTOKWDA
1255
1262
  vellum/types/workflow_result_event_output_data_number.py,sha256=TtQhFjBxV8zc036NkvBrYhWWHEmaUJk2RWAd1NKVtz0,178
1256
1263
  vellum/types/workflow_result_event_output_data_search_results.py,sha256=UNfCHLQ0jd5advLYdV7IBgmsRNzJ0PdDd3r2dNiIlgY,186
1257
1264
  vellum/types/workflow_result_event_output_data_string.py,sha256=rHEVbN0nyf-xoDoSIUEKlUKh6DDoguer4w0iN18JQ2I,178
1265
+ vellum/types/workflow_sandbox_example.py,sha256=PixQSt8aczB-oUT8qTL6k9nY-H2Mx7XvispKV0thUHM,162
1258
1266
  vellum/types/workflow_stream_event.py,sha256=PjHGgN0eJm5w-5FJ6__ASC1FU94Gsav_ko5JWkpVvK8,159
1259
1267
  vellum/types/workspace_read.py,sha256=9CvgvK8Li8vL6qC5KX7f3-nEHslJ4lw2w07bvXcrjA0,152
1260
1268
  vellum/types/workspace_secret_read.py,sha256=Z6QNXHxVHRdrLXSI31KxngePRwJTVoJYMXVbtPQwrxs,159
@@ -1406,9 +1414,9 @@ vellum/workflows/nodes/displayable/search_node/node.py,sha256=_VHHuTNN4icZBgc7O5
1406
1414
  vellum/workflows/nodes/displayable/search_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1407
1415
  vellum/workflows/nodes/displayable/search_node/tests/test_node.py,sha256=2-QCV7Vk_-YMls33p0GOUtCv3f2uPNZCjkB2CRjek7o,6562
1408
1416
  vellum/workflows/nodes/displayable/subworkflow_deployment_node/__init__.py,sha256=9yYM6001YZeqI1VOk1QuEM_yrffk_EdsO7qaPzINKds,92
1409
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py,sha256=sSRo_zX5QVI7V0qmReWMBkEa78HfQfjNIKwvKh7-Om8,8307
1417
+ vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py,sha256=9yqklkehUWLFhjIAC2WrkoMNqqvzHj1-hsuIVLXJHfo,8657
1410
1418
  vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1411
- vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py,sha256=c8RP-QnsERzIinVytAc0jVZ9nd7Jl3hbc9-_yG91Ros,5445
1419
+ vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py,sha256=qHnwn1KI4XpxM1b1zmCXEZUBxe5Sjk88ehxZ8HIGJQc,6353
1412
1420
  vellum/workflows/nodes/displayable/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1413
1421
  vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py,sha256=LaxohBcKfSW2PSiBBlx67FdW_q4YC2BM2ouH-vuGPAA,4700
1414
1422
  vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py,sha256=VepO5z1277c1y5N6LLIC31nnWD1aak2m5oPFplfJHHs,6935
@@ -1471,13 +1479,13 @@ vellum/workflows/utils/uuids.py,sha256=DFzPv9RCvsKhvdTEIQyfSek2A31D6S_QcmeLPbgrg
1471
1479
  vellum/workflows/utils/vellum_variables.py,sha256=fC2aSLvlS31D15dOWu43LBRR0QsgUKNXBiCUvvaLXSs,3231
1472
1480
  vellum/workflows/vellum_client.py,sha256=ODrq_TSl-drX2aezXegf7pizpWDVJuTXH-j6528t75s,683
1473
1481
  vellum/workflows/workflows/__init__.py,sha256=KY45TqvavCCvXIkyCFMEc0dc6jTMOUci93U2DUrlZYc,66
1474
- vellum/workflows/workflows/base.py,sha256=MNwWXt0xosrGAjbkQ_lhmBPlHzsJVX1Cr2qy7guFRK8,22446
1482
+ vellum/workflows/workflows/base.py,sha256=k3GfMDbhsa0pNGGHEaqJFbACyIJf_-wZMOz3FFtr_ls,22192
1475
1483
  vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnadGsrSZGa7t7LpJA,2008
1476
1484
  vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1477
1485
  vellum/workflows/workflows/tests/test_base_workflow.py,sha256=DTfXqHUF0SJELTVSA9PCOWHVoAylqpDNFZTkQM44CdU,6215
1478
1486
  vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
1479
- vellum_ai-0.14.5.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1480
- vellum_ai-0.14.5.dist-info/METADATA,sha256=_53R_GRMep--gP15bdsMgW6SYTC9AD_W9yvPkQp94w0,5407
1481
- vellum_ai-0.14.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1482
- vellum_ai-0.14.5.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1483
- vellum_ai-0.14.5.dist-info/RECORD,,
1487
+ vellum_ai-0.14.6.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1488
+ vellum_ai-0.14.6.dist-info/METADATA,sha256=gJeL8u5StNSUb5b8gENXqxj5mH0etlqQWLtWKBvE_eY,5407
1489
+ vellum_ai-0.14.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1490
+ vellum_ai-0.14.6.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1491
+ vellum_ai-0.14.6.dist-info/RECORD,,
@@ -7,6 +7,7 @@ from vellum.workflows.descriptors.base import BaseDescriptor
7
7
  from vellum.workflows.inputs import BaseInputs
8
8
  from vellum.workflows.nodes.bases import BaseNode
9
9
  from vellum.workflows.outputs import BaseOutputs
10
+ from vellum.workflows.references import LazyReference
10
11
  from vellum_ee.workflows.display.nodes.base_node_vellum_display import BaseNodeVellumDisplay
11
12
  from vellum_ee.workflows.display.nodes.types import NodeOutputDisplay
12
13
  from vellum_ee.workflows.display.nodes.vellum.utils import create_node_input_value_pointer_rules
@@ -43,6 +44,10 @@ class MyNodeADisplay(BaseNodeVellumDisplay[MyNodeA]):
43
44
  class MyNodeB(BaseNode):
44
45
  example = MyNodeA.Outputs.output
45
46
  fallback_example = MyNodeA.Outputs.output.coalesce(Inputs.example_workflow_input).coalesce("fallback")
47
+ constant_coalesce = Inputs.example_workflow_input.coalesce("default_value")
48
+ lazy_coalesce: BaseDescriptor[str] = LazyReference(
49
+ lambda: MyNodeA.Outputs.output.coalesce(Inputs.example_workflow_input)
50
+ )
46
51
 
47
52
 
48
53
  @pytest.mark.parametrize(
@@ -76,6 +81,32 @@ class MyNodeB(BaseNode):
76
81
  ConstantValuePointer(type="CONSTANT_VALUE", data=StringVellumValue(value="fallback")),
77
82
  ],
78
83
  ),
84
+ (
85
+ MyNodeB.constant_coalesce,
86
+ [
87
+ InputVariablePointer(
88
+ type="INPUT_VARIABLE",
89
+ data=InputVariableData(input_variable_id="a154c29d-fac0-4cd0-ba88-bc52034f5470"),
90
+ ),
91
+ ConstantValuePointer(type="CONSTANT_VALUE", data=StringVellumValue(value="default_value")),
92
+ ],
93
+ ),
94
+ (
95
+ MyNodeB.lazy_coalesce,
96
+ [
97
+ NodeOutputPointer(
98
+ type="NODE_OUTPUT",
99
+ data=NodeOutputData(
100
+ node_id="b48fa5e0-d7d3-4fe3-ae48-615415011cc5",
101
+ output_id="4b16a629-11a1-4b3f-a965-a57b872d13b8",
102
+ ),
103
+ ),
104
+ InputVariablePointer(
105
+ type="INPUT_VARIABLE",
106
+ data=InputVariableData(input_variable_id="a154c29d-fac0-4cd0-ba88-bc52034f5470"),
107
+ ),
108
+ ],
109
+ ),
79
110
  ],
80
111
  )
81
112
  def test_create_node_input_value_pointer_rules(
@@ -5,8 +5,10 @@ from vellum.workflows.descriptors.base import BaseDescriptor
5
5
  from vellum.workflows.expressions.coalesce_expression import CoalesceExpression
6
6
  from vellum.workflows.nodes.displayable.bases.utils import primitive_to_vellum_value
7
7
  from vellum.workflows.references import NodeReference
8
+ from vellum.workflows.references.lazy import LazyReference
8
9
  from vellum.workflows.utils.uuids import uuid4_from_hash
9
10
  from vellum_ee.workflows.display.types import WorkflowDisplayContext
11
+ from vellum_ee.workflows.display.utils.expressions import get_child_descriptor
10
12
  from vellum_ee.workflows.display.utils.vellum import create_node_input_value_pointer_rule
11
13
  from vellum_ee.workflows.display.vellum import (
12
14
  ConstantValuePointer,
@@ -56,6 +58,12 @@ def create_node_input_value_pointer_rules(
56
58
  raise ValueError(f"Expected NodeReference {value.name} to have an instance")
57
59
  value = cast(BaseDescriptor, value.instance)
58
60
 
61
+ if isinstance(value, LazyReference):
62
+ child_descriptor = get_child_descriptor(value, display_context)
63
+ return create_node_input_value_pointer_rules(
64
+ child_descriptor, display_context, [], pointer_type=pointer_type
65
+ )
66
+
59
67
  if isinstance(value, CoalesceExpression):
60
68
  # Recursively handle the left-hand side
61
69
  lhs_rules = create_node_input_value_pointer_rules(value.lhs, display_context, [], pointer_type=pointer_type)