vellum-ai 0.13.21__py3-none-any.whl → 0.13.22__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 (44) hide show
  1. vellum/__init__.py +12 -0
  2. vellum/client/__init__.py +170 -5
  3. vellum/client/core/client_wrapper.py +1 -1
  4. vellum/client/types/__init__.py +12 -0
  5. vellum/client/types/execute_api_request_bearer_token.py +6 -0
  6. vellum/client/types/execute_api_request_body.py +5 -0
  7. vellum/client/types/execute_api_request_headers_value.py +6 -0
  8. vellum/client/types/execute_api_response.py +24 -0
  9. vellum/client/types/method_enum.py +5 -0
  10. vellum/client/types/vellum_secret.py +19 -0
  11. vellum/plugins/pydantic.py +13 -1
  12. vellum/types/execute_api_request_bearer_token.py +3 -0
  13. vellum/types/execute_api_request_body.py +3 -0
  14. vellum/types/execute_api_request_headers_value.py +3 -0
  15. vellum/types/execute_api_response.py +3 -0
  16. vellum/types/method_enum.py +3 -0
  17. vellum/types/vellum_secret.py +3 -0
  18. vellum/workflows/nodes/core/inline_subworkflow_node/node.py +1 -0
  19. vellum/workflows/nodes/core/map_node/node.py +1 -0
  20. vellum/workflows/nodes/core/retry_node/node.py +1 -0
  21. vellum/workflows/nodes/core/try_node/node.py +11 -7
  22. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +11 -3
  23. vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +16 -10
  24. vellum/workflows/nodes/displayable/inline_prompt_node/tests/test_node.py +49 -0
  25. vellum/workflows/nodes/displayable/prompt_deployment_node/tests/__init__.py +0 -0
  26. vellum/workflows/nodes/displayable/prompt_deployment_node/tests/test_node.py +93 -0
  27. vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +19 -4
  28. vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/__init__.py +0 -0
  29. vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py +128 -0
  30. vellum/workflows/nodes/mocks.py +17 -0
  31. vellum/workflows/runner/runner.py +14 -34
  32. vellum/workflows/state/context.py +29 -1
  33. vellum/workflows/workflows/base.py +9 -6
  34. {vellum_ai-0.13.21.dist-info → vellum_ai-0.13.22.dist-info}/METADATA +1 -1
  35. {vellum_ai-0.13.21.dist-info → vellum_ai-0.13.22.dist-info}/RECORD +43 -26
  36. vellum_cli/push.py +5 -6
  37. vellum_cli/tests/test_push.py +81 -1
  38. vellum_ee/workflows/display/types.py +1 -31
  39. vellum_ee/workflows/display/workflows/base_workflow_display.py +46 -2
  40. vellum_ee/workflows/tests/test_server.py +9 -0
  41. vellum/workflows/types/cycle_map.py +0 -34
  42. {vellum_ai-0.13.21.dist-info → vellum_ai-0.13.22.dist-info}/LICENSE +0 -0
  43. {vellum_ai-0.13.21.dist-info → vellum_ai-0.13.22.dist-info}/WHEEL +0 -0
  44. {vellum_ai-0.13.21.dist-info → vellum_ai-0.13.22.dist-info}/entry_points.txt +0 -0
vellum/__init__.py CHANGED
@@ -92,6 +92,10 @@ from .types import (
92
92
  ErrorInput,
93
93
  ErrorVellumValue,
94
94
  ErrorVellumValueRequest,
95
+ ExecuteApiRequestBearerToken,
96
+ ExecuteApiRequestBody,
97
+ ExecuteApiRequestHeadersValue,
98
+ ExecuteApiResponse,
95
99
  ExecutePromptEvent,
96
100
  ExecutePromptResponse,
97
101
  ExecuteWorkflowResponse,
@@ -183,6 +187,7 @@ from .types import (
183
187
  MetadataFilterRuleCombinator,
184
188
  MetadataFilterRuleRequest,
185
189
  MetadataFiltersRequest,
190
+ MethodEnum,
186
191
  MetricDefinitionExecution,
187
192
  MetricDefinitionHistoryItem,
188
193
  MetricDefinitionInput,
@@ -437,6 +442,7 @@ from .types import (
437
442
  VellumErrorRequest,
438
443
  VellumImage,
439
444
  VellumImageRequest,
445
+ VellumSecret,
440
446
  VellumValue,
441
447
  VellumValueLogicalConditionGroupRequest,
442
448
  VellumValueLogicalConditionRequest,
@@ -617,6 +623,10 @@ __all__ = [
617
623
  "ErrorInput",
618
624
  "ErrorVellumValue",
619
625
  "ErrorVellumValueRequest",
626
+ "ExecuteApiRequestBearerToken",
627
+ "ExecuteApiRequestBody",
628
+ "ExecuteApiRequestHeadersValue",
629
+ "ExecuteApiResponse",
620
630
  "ExecutePromptEvent",
621
631
  "ExecutePromptResponse",
622
632
  "ExecuteWorkflowResponse",
@@ -713,6 +723,7 @@ __all__ = [
713
723
  "MetadataFilterRuleCombinator",
714
724
  "MetadataFilterRuleRequest",
715
725
  "MetadataFiltersRequest",
726
+ "MethodEnum",
716
727
  "MetricDefinitionExecution",
717
728
  "MetricDefinitionHistoryItem",
718
729
  "MetricDefinitionInput",
@@ -970,6 +981,7 @@ __all__ = [
970
981
  "VellumErrorRequest",
971
982
  "VellumImage",
972
983
  "VellumImageRequest",
984
+ "VellumSecret",
973
985
  "VellumValue",
974
986
  "VellumValueLogicalConditionGroupRequest",
975
987
  "VellumValueLogicalConditionRequest",
vellum/client/__init__.py CHANGED
@@ -21,17 +21,22 @@ from .resources.workflow_sandboxes.client import WorkflowSandboxesClient
21
21
  from .resources.workflows.client import WorkflowsClient
22
22
  from .resources.workspace_secrets.client import WorkspaceSecretsClient
23
23
  from .resources.workspaces.client import WorkspacesClient
24
+ from .types.method_enum import MethodEnum
25
+ from .types.execute_api_request_body import ExecuteApiRequestBody
26
+ from .types.execute_api_request_headers_value import ExecuteApiRequestHeadersValue
27
+ from .types.execute_api_request_bearer_token import ExecuteApiRequestBearerToken
28
+ from .core.request_options import RequestOptions
29
+ from .types.execute_api_response import ExecuteApiResponse
30
+ from .core.serialization import convert_and_respect_annotation_metadata
31
+ from .core.pydantic_utilities import parse_obj_as
32
+ from json.decoder import JSONDecodeError
33
+ from .core.api_error import ApiError
24
34
  from .types.code_execution_runtime import CodeExecutionRuntime
25
35
  from .types.code_executor_input import CodeExecutorInput
26
36
  from .types.code_execution_package import CodeExecutionPackage
27
37
  from .types.vellum_variable_type import VellumVariableType
28
- from .core.request_options import RequestOptions
29
38
  from .types.code_executor_response import CodeExecutorResponse
30
- from .core.serialization import convert_and_respect_annotation_metadata
31
- from .core.pydantic_utilities import parse_obj_as
32
39
  from .errors.bad_request_error import BadRequestError
33
- from json.decoder import JSONDecodeError
34
- from .core.api_error import ApiError
35
40
  from .types.prompt_deployment_input_request import PromptDeploymentInputRequest
36
41
  from .types.prompt_deployment_expand_meta_request import PromptDeploymentExpandMetaRequest
37
42
  from .types.raw_prompt_execution_overrides_request import RawPromptExecutionOverridesRequest
@@ -149,6 +154,82 @@ class Vellum:
149
154
  self.workspace_secrets = WorkspaceSecretsClient(client_wrapper=self._client_wrapper)
150
155
  self.workspaces = WorkspacesClient(client_wrapper=self._client_wrapper)
151
156
 
157
+ def execute_api(
158
+ self,
159
+ *,
160
+ url: str,
161
+ method: typing.Optional[MethodEnum] = OMIT,
162
+ body: typing.Optional[ExecuteApiRequestBody] = OMIT,
163
+ headers: typing.Optional[typing.Dict[str, ExecuteApiRequestHeadersValue]] = OMIT,
164
+ bearer_token: typing.Optional[ExecuteApiRequestBearerToken] = OMIT,
165
+ request_options: typing.Optional[RequestOptions] = None,
166
+ ) -> ExecuteApiResponse:
167
+ """
168
+ Parameters
169
+ ----------
170
+ url : str
171
+
172
+ method : typing.Optional[MethodEnum]
173
+
174
+ body : typing.Optional[ExecuteApiRequestBody]
175
+
176
+ headers : typing.Optional[typing.Dict[str, ExecuteApiRequestHeadersValue]]
177
+
178
+ bearer_token : typing.Optional[ExecuteApiRequestBearerToken]
179
+
180
+ request_options : typing.Optional[RequestOptions]
181
+ Request-specific configuration.
182
+
183
+ Returns
184
+ -------
185
+ ExecuteApiResponse
186
+
187
+
188
+ Examples
189
+ --------
190
+ from vellum import Vellum
191
+
192
+ client = Vellum(
193
+ api_key="YOUR_API_KEY",
194
+ )
195
+ client.execute_api(
196
+ url="url",
197
+ )
198
+ """
199
+ _response = self._client_wrapper.httpx_client.request(
200
+ "v1/execute-api",
201
+ base_url=self._client_wrapper.get_environment().default,
202
+ method="POST",
203
+ json={
204
+ "url": url,
205
+ "method": method,
206
+ "body": convert_and_respect_annotation_metadata(
207
+ object_=body, annotation=ExecuteApiRequestBody, direction="write"
208
+ ),
209
+ "headers": convert_and_respect_annotation_metadata(
210
+ object_=headers, annotation=typing.Dict[str, ExecuteApiRequestHeadersValue], direction="write"
211
+ ),
212
+ "bearer_token": convert_and_respect_annotation_metadata(
213
+ object_=bearer_token, annotation=ExecuteApiRequestBearerToken, direction="write"
214
+ ),
215
+ },
216
+ request_options=request_options,
217
+ omit=OMIT,
218
+ )
219
+ try:
220
+ if 200 <= _response.status_code < 300:
221
+ return typing.cast(
222
+ ExecuteApiResponse,
223
+ parse_obj_as(
224
+ type_=ExecuteApiResponse, # type: ignore
225
+ object_=_response.json(),
226
+ ),
227
+ )
228
+ _response_json = _response.json()
229
+ except JSONDecodeError:
230
+ raise ApiError(status_code=_response.status_code, body=_response.text)
231
+ raise ApiError(status_code=_response.status_code, body=_response_json)
232
+
152
233
  def execute_code(
153
234
  self,
154
235
  *,
@@ -1414,6 +1495,90 @@ class AsyncVellum:
1414
1495
  self.workspace_secrets = AsyncWorkspaceSecretsClient(client_wrapper=self._client_wrapper)
1415
1496
  self.workspaces = AsyncWorkspacesClient(client_wrapper=self._client_wrapper)
1416
1497
 
1498
+ async def execute_api(
1499
+ self,
1500
+ *,
1501
+ url: str,
1502
+ method: typing.Optional[MethodEnum] = OMIT,
1503
+ body: typing.Optional[ExecuteApiRequestBody] = OMIT,
1504
+ headers: typing.Optional[typing.Dict[str, ExecuteApiRequestHeadersValue]] = OMIT,
1505
+ bearer_token: typing.Optional[ExecuteApiRequestBearerToken] = OMIT,
1506
+ request_options: typing.Optional[RequestOptions] = None,
1507
+ ) -> ExecuteApiResponse:
1508
+ """
1509
+ Parameters
1510
+ ----------
1511
+ url : str
1512
+
1513
+ method : typing.Optional[MethodEnum]
1514
+
1515
+ body : typing.Optional[ExecuteApiRequestBody]
1516
+
1517
+ headers : typing.Optional[typing.Dict[str, ExecuteApiRequestHeadersValue]]
1518
+
1519
+ bearer_token : typing.Optional[ExecuteApiRequestBearerToken]
1520
+
1521
+ request_options : typing.Optional[RequestOptions]
1522
+ Request-specific configuration.
1523
+
1524
+ Returns
1525
+ -------
1526
+ ExecuteApiResponse
1527
+
1528
+
1529
+ Examples
1530
+ --------
1531
+ import asyncio
1532
+
1533
+ from vellum import AsyncVellum
1534
+
1535
+ client = AsyncVellum(
1536
+ api_key="YOUR_API_KEY",
1537
+ )
1538
+
1539
+
1540
+ async def main() -> None:
1541
+ await client.execute_api(
1542
+ url="url",
1543
+ )
1544
+
1545
+
1546
+ asyncio.run(main())
1547
+ """
1548
+ _response = await self._client_wrapper.httpx_client.request(
1549
+ "v1/execute-api",
1550
+ base_url=self._client_wrapper.get_environment().default,
1551
+ method="POST",
1552
+ json={
1553
+ "url": url,
1554
+ "method": method,
1555
+ "body": convert_and_respect_annotation_metadata(
1556
+ object_=body, annotation=ExecuteApiRequestBody, direction="write"
1557
+ ),
1558
+ "headers": convert_and_respect_annotation_metadata(
1559
+ object_=headers, annotation=typing.Dict[str, ExecuteApiRequestHeadersValue], direction="write"
1560
+ ),
1561
+ "bearer_token": convert_and_respect_annotation_metadata(
1562
+ object_=bearer_token, annotation=ExecuteApiRequestBearerToken, direction="write"
1563
+ ),
1564
+ },
1565
+ request_options=request_options,
1566
+ omit=OMIT,
1567
+ )
1568
+ try:
1569
+ if 200 <= _response.status_code < 300:
1570
+ return typing.cast(
1571
+ ExecuteApiResponse,
1572
+ parse_obj_as(
1573
+ type_=ExecuteApiResponse, # type: ignore
1574
+ object_=_response.json(),
1575
+ ),
1576
+ )
1577
+ _response_json = _response.json()
1578
+ except JSONDecodeError:
1579
+ raise ApiError(status_code=_response.status_code, body=_response.text)
1580
+ raise ApiError(status_code=_response.status_code, body=_response_json)
1581
+
1417
1582
  async def execute_code(
1418
1583
  self,
1419
1584
  *,
@@ -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.13.21",
21
+ "X-Fern-SDK-Version": "0.13.22",
22
22
  }
23
23
  headers["X_API_KEY"] = self.api_key
24
24
  return headers
@@ -96,6 +96,10 @@ from .ephemeral_prompt_cache_config_type_enum import EphemeralPromptCacheConfigT
96
96
  from .error_input import ErrorInput
97
97
  from .error_vellum_value import ErrorVellumValue
98
98
  from .error_vellum_value_request import ErrorVellumValueRequest
99
+ from .execute_api_request_bearer_token import ExecuteApiRequestBearerToken
100
+ from .execute_api_request_body import ExecuteApiRequestBody
101
+ from .execute_api_request_headers_value import ExecuteApiRequestHeadersValue
102
+ from .execute_api_response import ExecuteApiResponse
99
103
  from .execute_prompt_event import ExecutePromptEvent
100
104
  from .execute_prompt_response import ExecutePromptResponse
101
105
  from .execute_workflow_response import ExecuteWorkflowResponse
@@ -191,6 +195,7 @@ from .metadata_filter_config_request import MetadataFilterConfigRequest
191
195
  from .metadata_filter_rule_combinator import MetadataFilterRuleCombinator
192
196
  from .metadata_filter_rule_request import MetadataFilterRuleRequest
193
197
  from .metadata_filters_request import MetadataFiltersRequest
198
+ from .method_enum import MethodEnum
194
199
  from .metric_definition_execution import MetricDefinitionExecution
195
200
  from .metric_definition_history_item import MetricDefinitionHistoryItem
196
201
  from .metric_definition_input import MetricDefinitionInput
@@ -461,6 +466,7 @@ from .vellum_error_code_enum import VellumErrorCodeEnum
461
466
  from .vellum_error_request import VellumErrorRequest
462
467
  from .vellum_image import VellumImage
463
468
  from .vellum_image_request import VellumImageRequest
469
+ from .vellum_secret import VellumSecret
464
470
  from .vellum_value import VellumValue
465
471
  from .vellum_value_logical_condition_group_request import VellumValueLogicalConditionGroupRequest
466
472
  from .vellum_value_logical_condition_request import VellumValueLogicalConditionRequest
@@ -606,6 +612,10 @@ __all__ = [
606
612
  "ErrorInput",
607
613
  "ErrorVellumValue",
608
614
  "ErrorVellumValueRequest",
615
+ "ExecuteApiRequestBearerToken",
616
+ "ExecuteApiRequestBody",
617
+ "ExecuteApiRequestHeadersValue",
618
+ "ExecuteApiResponse",
609
619
  "ExecutePromptEvent",
610
620
  "ExecutePromptResponse",
611
621
  "ExecuteWorkflowResponse",
@@ -697,6 +707,7 @@ __all__ = [
697
707
  "MetadataFilterRuleCombinator",
698
708
  "MetadataFilterRuleRequest",
699
709
  "MetadataFiltersRequest",
710
+ "MethodEnum",
700
711
  "MetricDefinitionExecution",
701
712
  "MetricDefinitionHistoryItem",
702
713
  "MetricDefinitionInput",
@@ -951,6 +962,7 @@ __all__ = [
951
962
  "VellumErrorRequest",
952
963
  "VellumImage",
953
964
  "VellumImageRequest",
965
+ "VellumSecret",
954
966
  "VellumValue",
955
967
  "VellumValueLogicalConditionGroupRequest",
956
968
  "VellumValueLogicalConditionRequest",
@@ -0,0 +1,6 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from .vellum_secret import VellumSecret
5
+
6
+ ExecuteApiRequestBearerToken = typing.Union[str, VellumSecret]
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ ExecuteApiRequestBody = typing.Union[str, typing.Dict[str, typing.Optional[typing.Any]]]
@@ -0,0 +1,6 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from .vellum_secret import VellumSecret
5
+
6
+ ExecuteApiRequestHeadersValue = typing.Union[str, VellumSecret]
@@ -0,0 +1,24 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.pydantic_utilities import UniversalBaseModel
4
+ import typing_extensions
5
+ import typing
6
+ from ..core.serialization import FieldMetadata
7
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
8
+ import pydantic
9
+
10
+
11
+ class ExecuteApiResponse(UniversalBaseModel):
12
+ status_code: int
13
+ text: str
14
+ json_: typing_extensions.Annotated[typing.Dict[str, typing.Optional[typing.Any]], FieldMetadata(alias="json")]
15
+ headers: typing.Dict[str, str]
16
+
17
+ if IS_PYDANTIC_V2:
18
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
19
+ else:
20
+
21
+ class Config:
22
+ frozen = True
23
+ smart_union = True
24
+ extra = pydantic.Extra.allow
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ MethodEnum = typing.Union[typing.Literal["POST", "GET", "PATCH", "PUT", "DELETE"], typing.Any]
@@ -0,0 +1,19 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.pydantic_utilities import UniversalBaseModel
4
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
5
+ import typing
6
+ import pydantic
7
+
8
+
9
+ class VellumSecret(UniversalBaseModel):
10
+ name: str
11
+
12
+ if IS_PYDANTIC_V2:
13
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
14
+ else:
15
+
16
+ class Config:
17
+ frozen = True
18
+ smart_union = True
19
+ extra = pydantic.Extra.allow
@@ -1,6 +1,7 @@
1
1
  from functools import lru_cache
2
2
  from typing import Any, Dict, Literal, Optional, Tuple, Union
3
3
 
4
+ from pydantic.fields import FieldInfo
4
5
  from pydantic.plugin import (
5
6
  PydanticPluginProtocol,
6
7
  SchemaKind,
@@ -39,11 +40,22 @@ class OnValidatePython(ValidatePythonHandlerProtocol):
39
40
  if not isinstance(input, dict):
40
41
  return
41
42
 
43
+ if self_instance:
44
+ model_fields: Dict[str, FieldInfo] = self_instance.model_fields
45
+ else:
46
+ model_fields = {}
47
+
42
48
  self.tracked_descriptors = {}
43
49
  BaseDescriptor = import_base_descriptor()
44
50
 
45
51
  for key, value in input.items():
46
- if isinstance(value, BaseDescriptor):
52
+ field_info = model_fields.get(key)
53
+ if isinstance(value, BaseDescriptor) and (
54
+ not field_info
55
+ or not field_info.annotation
56
+ or not isinstance(field_info.annotation, type)
57
+ or not issubclass(field_info.annotation, BaseDescriptor)
58
+ ):
47
59
  self.tracked_descriptors[key] = value
48
60
  # TODO: This does not yet work for descriptors that map to more complex types
49
61
  # https://app.shortcut.com/vellum/story/4636
@@ -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.execute_api_request_bearer_token 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.execute_api_request_body 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.execute_api_request_headers_value 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.execute_api_response 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.method_enum 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.vellum_secret import *
@@ -78,6 +78,7 @@ class InlineSubworkflowNode(
78
78
  subworkflow_stream = subworkflow.stream(
79
79
  inputs=self._compile_subworkflow_inputs(),
80
80
  event_filter=all_workflow_event_filter,
81
+ node_output_mocks=self._context._get_all_node_output_mocks(),
81
82
  )
82
83
 
83
84
  outputs: Optional[BaseOutputs] = None
@@ -152,6 +152,7 @@ class MapNode(BaseAdornmentNode[StateType], Generic[StateType, MapNodeItemType])
152
152
  )
153
153
  events = subworkflow.stream(
154
154
  inputs=self.SubworkflowInputs(index=index, item=item, all_items=self.items),
155
+ node_output_mocks=self._context._get_all_node_output_mocks(),
155
156
  event_filter=all_workflow_event_filter,
156
157
  )
157
158
 
@@ -44,6 +44,7 @@ class RetryNode(BaseAdornmentNode[StateType], Generic[StateType]):
44
44
  )
45
45
  terminal_event = subworkflow.run(
46
46
  inputs=self.SubworkflowInputs(attempt_number=attempt_number),
47
+ node_output_mocks=self._context._get_all_node_output_mocks(),
47
48
  )
48
49
  if terminal_event.name == "workflow.execution.fulfilled":
49
50
  node_outputs = self.Outputs()
@@ -1,5 +1,6 @@
1
1
  from typing import Callable, Generic, Iterator, Optional, Set, Type
2
2
 
3
+ from vellum.workflows.context import execution_context, get_parent_context
3
4
  from vellum.workflows.errors.types import WorkflowError, WorkflowErrorCode
4
5
  from vellum.workflows.exceptions import NodeException
5
6
  from vellum.workflows.nodes.bases import BaseNode
@@ -26,13 +27,16 @@ class TryNode(BaseAdornmentNode[StateType], Generic[StateType]):
26
27
  error: Optional[WorkflowError] = None
27
28
 
28
29
  def run(self) -> Iterator[BaseOutput]:
29
- subworkflow = self.subworkflow(
30
- parent_state=self.state,
31
- context=WorkflowContext(vellum_client=self._context.vellum_client),
32
- )
33
- subworkflow_stream = subworkflow.stream(
34
- event_filter=all_workflow_event_filter,
35
- )
30
+ parent_context = get_parent_context() or self._context.parent_context
31
+ with execution_context(parent_context=parent_context):
32
+ subworkflow = self.subworkflow(
33
+ parent_state=self.state,
34
+ context=WorkflowContext(vellum_client=self._context.vellum_client),
35
+ )
36
+ subworkflow_stream = subworkflow.stream(
37
+ event_filter=all_workflow_event_filter,
38
+ node_output_mocks=self._context._get_all_node_output_mocks(),
39
+ )
36
40
 
37
41
  outputs: Optional[BaseOutputs] = None
38
42
  exception: Optional[NodeException] = None
@@ -1,6 +1,6 @@
1
1
  import json
2
2
  from uuid import uuid4
3
- from typing import Callable, ClassVar, Generic, Iterator, List, Optional, Tuple, Union, cast
3
+ from typing import Callable, ClassVar, Generic, Iterator, List, Optional, Tuple, Union
4
4
 
5
5
  from vellum import (
6
6
  AdHocExecutePromptEvent,
@@ -16,6 +16,7 @@ from vellum import (
16
16
  VellumVariable,
17
17
  )
18
18
  from vellum.client import RequestOptions
19
+ from vellum.client.types.chat_message_request import ChatMessageRequest
19
20
  from vellum.workflows.constants import OMIT
20
21
  from vellum.workflows.context import get_parent_context
21
22
  from vellum.workflows.errors import WorkflowErrorCode
@@ -108,7 +109,14 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
108
109
  value=input_value,
109
110
  )
110
111
  )
111
- elif isinstance(input_value, list) and all(isinstance(message, ChatMessage) for message in input_value):
112
+ elif isinstance(input_value, list) and all(
113
+ isinstance(message, (ChatMessage, ChatMessageRequest)) for message in input_value
114
+ ):
115
+ chat_history = [
116
+ message if isinstance(message, ChatMessage) else ChatMessage.model_validate(message.model_dump())
117
+ for message in input_value
118
+ if isinstance(message, (ChatMessage, ChatMessageRequest))
119
+ ]
112
120
  input_variables.append(
113
121
  VellumVariable(
114
122
  # TODO: Determine whether or not we actually need an id here and if we do,
@@ -122,7 +130,7 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
122
130
  input_values.append(
123
131
  PromptRequestChatHistoryInput(
124
132
  key=input_name,
125
- value=cast(List[ChatMessage], input_value),
133
+ value=chat_history,
126
134
  )
127
135
  )
128
136
  else:
@@ -1,3 +1,4 @@
1
+ import json
1
2
  from uuid import UUID
2
3
  from typing import Any, ClassVar, Dict, Generic, Iterator, List, Optional, Sequence, Union, cast
3
4
 
@@ -12,9 +13,11 @@ from vellum import (
12
13
  StringInputRequest,
13
14
  )
14
15
  from vellum.client import RequestOptions
16
+ from vellum.client.types.chat_message_request import ChatMessageRequest
15
17
  from vellum.workflows.constants import LATEST_RELEASE_TAG, OMIT
16
18
  from vellum.workflows.context import get_parent_context
17
19
  from vellum.workflows.errors import WorkflowErrorCode
20
+ from vellum.workflows.events.types import default_serializer
18
21
  from vellum.workflows.exceptions import NodeException
19
22
  from vellum.workflows.nodes.displayable.bases.base_prompt_node import BasePromptNode
20
23
  from vellum.workflows.types import MergeBehavior
@@ -89,26 +92,29 @@ class BasePromptDeploymentNode(BasePromptNode, Generic[StateType]):
89
92
  value=input_value,
90
93
  )
91
94
  )
92
- elif isinstance(input_value, list) and all(isinstance(message, ChatMessage) for message in input_value):
95
+ elif isinstance(input_value, list) and all(
96
+ isinstance(message, (ChatMessage, ChatMessageRequest)) for message in input_value
97
+ ):
93
98
  compiled_inputs.append(
94
99
  ChatHistoryInputRequest(
95
100
  name=input_name,
96
101
  value=cast(List[ChatMessage], input_value),
97
102
  )
98
103
  )
99
- elif isinstance(input_value, dict):
100
- # Note: We may want to fail early here if we know that input_value is not
101
- # JSON serializable.
104
+ else:
105
+ try:
106
+ input_value = default_serializer(input_value)
107
+ except json.JSONDecodeError as e:
108
+ raise NodeException(
109
+ message=f"Failed to serialize input '{input_name}' of type '{input_value.__class__}': {e}",
110
+ code=WorkflowErrorCode.INVALID_INPUTS,
111
+ )
112
+
102
113
  compiled_inputs.append(
103
114
  JsonInputRequest(
104
115
  name=input_name,
105
- value=cast(Dict[str, Any], input_value),
116
+ value=input_value,
106
117
  )
107
118
  )
108
- else:
109
- raise NodeException(
110
- message=f"Unrecognized input type for input '{input_name}': {input_value.__class__}",
111
- code=WorkflowErrorCode.INVALID_INPUTS,
112
- )
113
119
 
114
120
  return compiled_inputs