vellum-ai 0.14.4__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 (39) 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/context.py +8 -3
  17. vellum/workflows/nodes/displayable/code_execution_node/tests/test_code_execution_node.py +81 -1
  18. vellum/workflows/nodes/displayable/code_execution_node/utils.py +44 -20
  19. vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +17 -10
  20. vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +12 -2
  21. vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py +23 -0
  22. vellum/workflows/workflows/base.py +61 -53
  23. vellum/workflows/workflows/tests/test_base_workflow.py +47 -0
  24. vellum/workflows/workflows/tests/test_context.py +60 -0
  25. {vellum_ai-0.14.4.dist-info → vellum_ai-0.14.6.dist-info}/METADATA +1 -1
  26. {vellum_ai-0.14.4.dist-info → vellum_ai-0.14.6.dist-info}/RECORD +39 -29
  27. vellum_ee/workflows/display/nodes/vellum/__init__.py +2 -0
  28. vellum_ee/workflows/display/nodes/vellum/base_adornment_node.py +39 -0
  29. vellum_ee/workflows/display/nodes/vellum/map_node.py +2 -2
  30. vellum_ee/workflows/display/nodes/vellum/retry_node.py +36 -4
  31. vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +31 -0
  32. vellum_ee/workflows/display/nodes/vellum/try_node.py +43 -29
  33. vellum_ee/workflows/display/nodes/vellum/utils.py +8 -0
  34. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +25 -1
  35. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +14 -0
  36. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py +19 -1
  37. {vellum_ai-0.14.4.dist-info → vellum_ai-0.14.6.dist-info}/LICENSE +0 -0
  38. {vellum_ai-0.14.4.dist-info → vellum_ai-0.14.6.dist-info}/WHEEL +0 -0
  39. {vellum_ai-0.14.4.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.4",
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 *
@@ -1,5 +1,6 @@
1
1
  from contextlib import contextmanager
2
2
  import threading
3
+ from uuid import UUID
3
4
  from typing import Iterator, Optional, cast
4
5
 
5
6
  from vellum.client.core import UniversalBaseModel
@@ -8,6 +9,7 @@ from vellum.workflows.events.types import ParentContext
8
9
 
9
10
  class ExecutionContext(UniversalBaseModel):
10
11
  parent_context: Optional[ParentContext] = None
12
+ trace_id: Optional[UUID] = None
11
13
 
12
14
 
13
15
  _CONTEXT_KEY = "_execution_context"
@@ -30,11 +32,14 @@ def get_parent_context() -> ParentContext:
30
32
 
31
33
 
32
34
  @contextmanager
33
- def execution_context(parent_context: Optional[ParentContext] = None) -> Iterator[None]:
35
+ def execution_context(
36
+ parent_context: Optional[ParentContext] = None, trace_id: Optional[UUID] = None
37
+ ) -> Iterator[None]:
34
38
  """Context manager for handling execution context."""
35
39
  prev_context = get_execution_context()
36
- set_context = ExecutionContext(parent_context=parent_context) if parent_context else prev_context
37
-
40
+ set_trace_id = prev_context.trace_id or trace_id
41
+ set_parent_context = parent_context or prev_context.parent_context
42
+ set_context = ExecutionContext(parent_context=set_parent_context, trace_id=set_trace_id)
38
43
  try:
39
44
  set_execution_context(set_context)
40
45
  yield
@@ -1,12 +1,16 @@
1
1
  import pytest
2
2
  import os
3
- from typing import Any, Union
3
+ from typing import Any, List, Union
4
+
5
+ from pydantic import BaseModel
4
6
 
5
7
  from vellum import CodeExecutorResponse, NumberVellumValue, StringInput, StringVellumValue
8
+ from vellum.client.types.chat_message import ChatMessage
6
9
  from vellum.client.types.code_execution_package import CodeExecutionPackage
7
10
  from vellum.client.types.code_executor_secret_input import CodeExecutorSecretInput
8
11
  from vellum.client.types.function_call import FunctionCall
9
12
  from vellum.client.types.number_input import NumberInput
13
+ from vellum.client.types.string_chat_message_content import StringChatMessageContent
10
14
  from vellum.workflows.errors import WorkflowErrorCode
11
15
  from vellum.workflows.exceptions import NodeException
12
16
  from vellum.workflows.inputs.base import BaseInputs
@@ -610,3 +614,79 @@ def main(arg1: list[bool]) -> int:
610
614
 
611
615
  # AND the error should contain the execution error details
612
616
  assert outputs == {"result": 3, "log": ""}
617
+
618
+
619
+ def test_run_node__union_output_type__pydantic_children():
620
+ # GIVEN a node that is a union type with a pydantic child
621
+ class OptionOne(BaseModel):
622
+ foo: str
623
+
624
+ class OptionTwo(BaseModel):
625
+ bar: int
626
+
627
+ class ExampleCodeExecutionNode(CodeExecutionNode[BaseState, Union[OptionOne, OptionTwo]]):
628
+ code = """\
629
+ def main():
630
+ return { "foo": "hello" }
631
+ """
632
+ runtime = "PYTHON_3_11_6"
633
+ code_inputs = {}
634
+
635
+ # WHEN we run the node
636
+ node = ExampleCodeExecutionNode()
637
+
638
+ # THEN it should run successfully
639
+ outputs = node.run()
640
+
641
+ # AND the result should be the correct type
642
+ assert outputs == {"result": OptionOne(foo="hello"), "log": ""}
643
+
644
+
645
+ def test_run_node__union_output_type__miss():
646
+ # GIVEN a node that is a union type
647
+ class ExampleCodeExecutionNode(CodeExecutionNode[BaseState, Union[int, float]]):
648
+ code = """\
649
+ def main():
650
+ return "hello"
651
+ """
652
+ runtime = "PYTHON_3_11_6"
653
+ code_inputs = {}
654
+
655
+ # WHEN we run the node
656
+ node = ExampleCodeExecutionNode()
657
+
658
+ # THEN it should raise a NodeException with the execution error
659
+ with pytest.raises(NodeException) as exc_info:
660
+ node.run()
661
+
662
+ # AND the error should contain the execution error details
663
+ assert exc_info.value.message == "Expected an output of type 'int | float', but received 'str'"
664
+
665
+
666
+ def test_run_node__chat_history_output_type():
667
+ # GIVEN a node that that has a chat history return type
668
+ class ExampleCodeExecutionNode(CodeExecutionNode[BaseState, List[ChatMessage]]):
669
+ code = """\
670
+ def main():
671
+ return [
672
+ {
673
+ "role": "USER",
674
+ "content": {
675
+ "type": "STRING",
676
+ "value": "Hello, world!",
677
+ }
678
+ }
679
+ ]
680
+ """
681
+ code_inputs = {}
682
+ runtime = "PYTHON_3_11_6"
683
+
684
+ # WHEN we run the node
685
+ node = ExampleCodeExecutionNode()
686
+ outputs = node.run()
687
+
688
+ # AND the error should contain the execution error details
689
+ assert outputs == {
690
+ "result": [ChatMessage(role="USER", content=StringChatMessageContent(value="Hello, world!"))],
691
+ "log": "",
692
+ }
@@ -67,6 +67,49 @@ def _clean_for_dict_wrapper(obj):
67
67
  return obj
68
68
 
69
69
 
70
+ def _get_type_name(obj: Any) -> str:
71
+ if isinstance(obj, type):
72
+ return obj.__name__
73
+
74
+ if get_origin(obj) is Union:
75
+ children = [_get_type_name(child) for child in get_args(obj)]
76
+ return " | ".join(children)
77
+
78
+ return str(obj)
79
+
80
+
81
+ def _cast_to_output_type(result: Any, output_type: Any) -> Any:
82
+ is_valid_output_type = isinstance(output_type, type)
83
+ if get_origin(output_type) is Union:
84
+ allowed_types = get_args(output_type)
85
+ for allowed_type in allowed_types:
86
+ try:
87
+ return _cast_to_output_type(result, allowed_type)
88
+ except NodeException:
89
+ continue
90
+ elif get_origin(output_type) is list:
91
+ allowed_item_type = get_args(output_type)[0]
92
+ if isinstance(result, list):
93
+ return [_cast_to_output_type(item, allowed_item_type) for item in result]
94
+ elif is_valid_output_type and issubclass(output_type, BaseModel) and not isinstance(result, output_type):
95
+ try:
96
+ return output_type.model_validate(result)
97
+ except ValidationError as e:
98
+ raise NodeException(
99
+ code=WorkflowErrorCode.INVALID_OUTPUTS,
100
+ message=re.sub(r"\s+For further information visit [^\s]+", "", str(e)),
101
+ ) from e
102
+ elif is_valid_output_type and isinstance(result, output_type):
103
+ return result
104
+
105
+ output_type_name = _get_type_name(output_type)
106
+ result_type_name = _get_type_name(type(result))
107
+ raise NodeException(
108
+ code=WorkflowErrorCode.INVALID_OUTPUTS,
109
+ message=f"Expected an output of type '{output_type_name}', but received '{result_type_name}'",
110
+ )
111
+
112
+
70
113
  def run_code_inline(
71
114
  code: str,
72
115
  inputs: EntityInputsInterface,
@@ -112,25 +155,6 @@ __arg__out = main({", ".join(run_args)})
112
155
  result = exec_globals["__arg__out"]
113
156
 
114
157
  if output_type != Any:
115
- if get_origin(output_type) is Union:
116
- allowed_types = get_args(output_type)
117
- if not isinstance(result, allowed_types):
118
- raise NodeException(
119
- code=WorkflowErrorCode.INVALID_OUTPUTS,
120
- message=f"Expected output to be in types {allowed_types}, but received '{type(result).__name__}'",
121
- )
122
- elif issubclass(output_type, BaseModel) and not isinstance(result, output_type):
123
- try:
124
- result = output_type.model_validate(result)
125
- except ValidationError as e:
126
- raise NodeException(
127
- code=WorkflowErrorCode.INVALID_OUTPUTS,
128
- message=re.sub(r"\s+For further information visit [^\s]+", "", str(e)),
129
- ) from e
130
- elif not isinstance(result, output_type):
131
- raise NodeException(
132
- code=WorkflowErrorCode.INVALID_OUTPUTS,
133
- message=f"Expected an output of type '{output_type.__name__}', but received '{type(result).__name__}'",
134
- )
158
+ result = _cast_to_output_type(result, output_type)
135
159
 
136
160
  return logs, result