vellum-ai 1.3.1__py3-none-any.whl → 1.3.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vellum/__init__.py +6 -0
- vellum/client/README.md +5 -5
- vellum/client/__init__.py +20 -0
- vellum/client/core/client_wrapper.py +2 -2
- vellum/client/raw_client.py +20 -0
- vellum/client/reference.md +61 -27
- vellum/client/resources/ad_hoc/client.py +29 -29
- vellum/client/resources/ad_hoc/raw_client.py +13 -13
- vellum/client/resources/events/client.py +69 -33
- vellum/client/resources/events/raw_client.py +13 -9
- vellum/client/types/__init__.py +6 -0
- vellum/client/types/create_workflow_event_request.py +7 -0
- vellum/client/types/deprecated_prompt_request_input.py +8 -0
- vellum/client/types/event_create_response.py +5 -0
- vellum/client/types/logical_operator.py +1 -0
- vellum/client/types/processing_failure_reason_enum.py +3 -1
- vellum/client/types/slim_document.py +1 -0
- vellum/client/types/workflow_input.py +31 -0
- vellum/types/create_workflow_event_request.py +3 -0
- vellum/types/deprecated_prompt_request_input.py +3 -0
- vellum/types/workflow_input.py +3 -0
- vellum/workflows/constants.py +3 -0
- vellum/workflows/events/node.py +1 -0
- vellum/workflows/events/tests/test_event.py +1 -0
- vellum/workflows/events/workflow.py +1 -0
- vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py +16 -0
- vellum/workflows/nodes/displayable/code_execution_node/tests/test_node.py +3 -13
- vellum/workflows/nodes/tests/test_utils.py +23 -0
- vellum/workflows/nodes/utils.py +14 -0
- vellum/workflows/runner/runner.py +33 -12
- vellum/workflows/types/code_execution_node_wrappers.py +2 -1
- {vellum_ai-1.3.1.dist-info → vellum_ai-1.3.2.dist-info}/METADATA +1 -1
- {vellum_ai-1.3.1.dist-info → vellum_ai-1.3.2.dist-info}/RECORD +37 -30
- vellum_ee/workflows/display/tests/workflow_serialization/test_web_search_node_serialization.py +81 -0
- {vellum_ai-1.3.1.dist-info → vellum_ai-1.3.2.dist-info}/LICENSE +0 -0
- {vellum_ai-1.3.1.dist-info → vellum_ai-1.3.2.dist-info}/WHEEL +0 -0
- {vellum_ai-1.3.1.dist-info → vellum_ai-1.3.2.dist-info}/entry_points.txt +0 -0
@@ -16,10 +16,10 @@ from ...errors.forbidden_error import ForbiddenError
|
|
16
16
|
from ...errors.internal_server_error import InternalServerError
|
17
17
|
from ...types.ad_hoc_execute_prompt_event import AdHocExecutePromptEvent
|
18
18
|
from ...types.ad_hoc_expand_meta import AdHocExpandMeta
|
19
|
+
from ...types.deprecated_prompt_request_input import DeprecatedPromptRequestInput
|
19
20
|
from ...types.function_definition import FunctionDefinition
|
20
21
|
from ...types.prompt_block import PromptBlock
|
21
22
|
from ...types.prompt_parameters import PromptParameters
|
22
|
-
from ...types.prompt_request_input import PromptRequestInput
|
23
23
|
from ...types.prompt_settings import PromptSettings
|
24
24
|
from ...types.vellum_variable import VellumVariable
|
25
25
|
|
@@ -35,7 +35,7 @@ class RawAdHocClient:
|
|
35
35
|
self,
|
36
36
|
*,
|
37
37
|
ml_model: str,
|
38
|
-
input_values: typing.Sequence[
|
38
|
+
input_values: typing.Sequence[DeprecatedPromptRequestInput],
|
39
39
|
input_variables: typing.Sequence[VellumVariable],
|
40
40
|
parameters: PromptParameters,
|
41
41
|
blocks: typing.Sequence[PromptBlock],
|
@@ -49,7 +49,7 @@ class RawAdHocClient:
|
|
49
49
|
----------
|
50
50
|
ml_model : str
|
51
51
|
|
52
|
-
input_values : typing.Sequence[
|
52
|
+
input_values : typing.Sequence[DeprecatedPromptRequestInput]
|
53
53
|
|
54
54
|
input_variables : typing.Sequence[VellumVariable]
|
55
55
|
|
@@ -78,7 +78,7 @@ class RawAdHocClient:
|
|
78
78
|
json={
|
79
79
|
"ml_model": ml_model,
|
80
80
|
"input_values": convert_and_respect_annotation_metadata(
|
81
|
-
object_=input_values, annotation=typing.Sequence[
|
81
|
+
object_=input_values, annotation=typing.Sequence[DeprecatedPromptRequestInput], direction="write"
|
82
82
|
),
|
83
83
|
"input_variables": convert_and_respect_annotation_metadata(
|
84
84
|
object_=input_variables, annotation=typing.Sequence[VellumVariable], direction="write"
|
@@ -160,7 +160,7 @@ class RawAdHocClient:
|
|
160
160
|
self,
|
161
161
|
*,
|
162
162
|
ml_model: str,
|
163
|
-
input_values: typing.Sequence[
|
163
|
+
input_values: typing.Sequence[DeprecatedPromptRequestInput],
|
164
164
|
input_variables: typing.Sequence[VellumVariable],
|
165
165
|
parameters: PromptParameters,
|
166
166
|
blocks: typing.Sequence[PromptBlock],
|
@@ -174,7 +174,7 @@ class RawAdHocClient:
|
|
174
174
|
----------
|
175
175
|
ml_model : str
|
176
176
|
|
177
|
-
input_values : typing.Sequence[
|
177
|
+
input_values : typing.Sequence[DeprecatedPromptRequestInput]
|
178
178
|
|
179
179
|
input_variables : typing.Sequence[VellumVariable]
|
180
180
|
|
@@ -203,7 +203,7 @@ class RawAdHocClient:
|
|
203
203
|
json={
|
204
204
|
"ml_model": ml_model,
|
205
205
|
"input_values": convert_and_respect_annotation_metadata(
|
206
|
-
object_=input_values, annotation=typing.Sequence[
|
206
|
+
object_=input_values, annotation=typing.Sequence[DeprecatedPromptRequestInput], direction="write"
|
207
207
|
),
|
208
208
|
"input_variables": convert_and_respect_annotation_metadata(
|
209
209
|
object_=input_variables, annotation=typing.Sequence[VellumVariable], direction="write"
|
@@ -306,7 +306,7 @@ class AsyncRawAdHocClient:
|
|
306
306
|
self,
|
307
307
|
*,
|
308
308
|
ml_model: str,
|
309
|
-
input_values: typing.Sequence[
|
309
|
+
input_values: typing.Sequence[DeprecatedPromptRequestInput],
|
310
310
|
input_variables: typing.Sequence[VellumVariable],
|
311
311
|
parameters: PromptParameters,
|
312
312
|
blocks: typing.Sequence[PromptBlock],
|
@@ -320,7 +320,7 @@ class AsyncRawAdHocClient:
|
|
320
320
|
----------
|
321
321
|
ml_model : str
|
322
322
|
|
323
|
-
input_values : typing.Sequence[
|
323
|
+
input_values : typing.Sequence[DeprecatedPromptRequestInput]
|
324
324
|
|
325
325
|
input_variables : typing.Sequence[VellumVariable]
|
326
326
|
|
@@ -349,7 +349,7 @@ class AsyncRawAdHocClient:
|
|
349
349
|
json={
|
350
350
|
"ml_model": ml_model,
|
351
351
|
"input_values": convert_and_respect_annotation_metadata(
|
352
|
-
object_=input_values, annotation=typing.Sequence[
|
352
|
+
object_=input_values, annotation=typing.Sequence[DeprecatedPromptRequestInput], direction="write"
|
353
353
|
),
|
354
354
|
"input_variables": convert_and_respect_annotation_metadata(
|
355
355
|
object_=input_variables, annotation=typing.Sequence[VellumVariable], direction="write"
|
@@ -431,7 +431,7 @@ class AsyncRawAdHocClient:
|
|
431
431
|
self,
|
432
432
|
*,
|
433
433
|
ml_model: str,
|
434
|
-
input_values: typing.Sequence[
|
434
|
+
input_values: typing.Sequence[DeprecatedPromptRequestInput],
|
435
435
|
input_variables: typing.Sequence[VellumVariable],
|
436
436
|
parameters: PromptParameters,
|
437
437
|
blocks: typing.Sequence[PromptBlock],
|
@@ -445,7 +445,7 @@ class AsyncRawAdHocClient:
|
|
445
445
|
----------
|
446
446
|
ml_model : str
|
447
447
|
|
448
|
-
input_values : typing.Sequence[
|
448
|
+
input_values : typing.Sequence[DeprecatedPromptRequestInput]
|
449
449
|
|
450
450
|
input_variables : typing.Sequence[VellumVariable]
|
451
451
|
|
@@ -474,7 +474,7 @@ class AsyncRawAdHocClient:
|
|
474
474
|
json={
|
475
475
|
"ml_model": ml_model,
|
476
476
|
"input_values": convert_and_respect_annotation_metadata(
|
477
|
-
object_=input_values, annotation=typing.Sequence[
|
477
|
+
object_=input_values, annotation=typing.Sequence[DeprecatedPromptRequestInput], direction="write"
|
478
478
|
),
|
479
479
|
"input_variables": convert_and_respect_annotation_metadata(
|
480
480
|
object_=input_variables, annotation=typing.Sequence[VellumVariable], direction="write"
|
@@ -4,8 +4,8 @@ import typing
|
|
4
4
|
|
5
5
|
from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
|
6
6
|
from ...core.request_options import RequestOptions
|
7
|
+
from ...types.create_workflow_event_request import CreateWorkflowEventRequest
|
7
8
|
from ...types.event_create_response import EventCreateResponse
|
8
|
-
from ...types.workflow_event import WorkflowEvent
|
9
9
|
from .raw_client import AsyncRawEventsClient, RawEventsClient
|
10
10
|
|
11
11
|
# this is used as the default value for optional parameters
|
@@ -32,14 +32,14 @@ class EventsClient:
|
|
32
32
|
return self._raw_client
|
33
33
|
|
34
34
|
def create(
|
35
|
-
self, *, request:
|
35
|
+
self, *, request: CreateWorkflowEventRequest, request_options: typing.Optional[RequestOptions] = None
|
36
36
|
) -> EventCreateResponse:
|
37
37
|
"""
|
38
|
-
Accept an event and publish
|
38
|
+
Accept an event or list of events and publish them to ClickHouse for analytics processing.
|
39
39
|
|
40
40
|
Parameters
|
41
41
|
----------
|
42
|
-
request :
|
42
|
+
request : CreateWorkflowEventRequest
|
43
43
|
|
44
44
|
request_options : typing.Optional[RequestOptions]
|
45
45
|
Request-specific configuration.
|
@@ -65,22 +65,40 @@ class EventsClient:
|
|
65
65
|
api_key="YOUR_API_KEY",
|
66
66
|
)
|
67
67
|
client.events.create(
|
68
|
-
request=
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
68
|
+
request=[
|
69
|
+
NodeExecutionInitiatedEvent(
|
70
|
+
body=NodeExecutionInitiatedBody(
|
71
|
+
node_definition=VellumCodeResourceDefinition(
|
72
|
+
name="name",
|
73
|
+
module=["module", "module"],
|
74
|
+
id="id",
|
75
|
+
),
|
76
|
+
inputs={"inputs": {"key": "value"}},
|
77
|
+
),
|
78
|
+
id="id",
|
79
|
+
timestamp=datetime.datetime.fromisoformat(
|
80
|
+
"2024-01-15 09:30:00+00:00",
|
74
81
|
),
|
75
|
-
|
82
|
+
trace_id="trace_id",
|
83
|
+
span_id="span_id",
|
76
84
|
),
|
77
|
-
|
78
|
-
|
79
|
-
|
85
|
+
NodeExecutionInitiatedEvent(
|
86
|
+
body=NodeExecutionInitiatedBody(
|
87
|
+
node_definition=VellumCodeResourceDefinition(
|
88
|
+
name="name",
|
89
|
+
module=["module", "module"],
|
90
|
+
id="id",
|
91
|
+
),
|
92
|
+
inputs={"inputs": {"key": "value"}},
|
93
|
+
),
|
94
|
+
id="id",
|
95
|
+
timestamp=datetime.datetime.fromisoformat(
|
96
|
+
"2024-01-15 09:30:00+00:00",
|
97
|
+
),
|
98
|
+
trace_id="trace_id",
|
99
|
+
span_id="span_id",
|
80
100
|
),
|
81
|
-
|
82
|
-
span_id="span_id",
|
83
|
-
),
|
101
|
+
],
|
84
102
|
)
|
85
103
|
"""
|
86
104
|
_response = self._raw_client.create(request=request, request_options=request_options)
|
@@ -103,14 +121,14 @@ class AsyncEventsClient:
|
|
103
121
|
return self._raw_client
|
104
122
|
|
105
123
|
async def create(
|
106
|
-
self, *, request:
|
124
|
+
self, *, request: CreateWorkflowEventRequest, request_options: typing.Optional[RequestOptions] = None
|
107
125
|
) -> EventCreateResponse:
|
108
126
|
"""
|
109
|
-
Accept an event and publish
|
127
|
+
Accept an event or list of events and publish them to ClickHouse for analytics processing.
|
110
128
|
|
111
129
|
Parameters
|
112
130
|
----------
|
113
|
-
request :
|
131
|
+
request : CreateWorkflowEventRequest
|
114
132
|
|
115
133
|
request_options : typing.Optional[RequestOptions]
|
116
134
|
Request-specific configuration.
|
@@ -140,22 +158,40 @@ class AsyncEventsClient:
|
|
140
158
|
|
141
159
|
async def main() -> None:
|
142
160
|
await client.events.create(
|
143
|
-
request=
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
161
|
+
request=[
|
162
|
+
NodeExecutionInitiatedEvent(
|
163
|
+
body=NodeExecutionInitiatedBody(
|
164
|
+
node_definition=VellumCodeResourceDefinition(
|
165
|
+
name="name",
|
166
|
+
module=["module", "module"],
|
167
|
+
id="id",
|
168
|
+
),
|
169
|
+
inputs={"inputs": {"key": "value"}},
|
149
170
|
),
|
150
|
-
|
171
|
+
id="id",
|
172
|
+
timestamp=datetime.datetime.fromisoformat(
|
173
|
+
"2024-01-15 09:30:00+00:00",
|
174
|
+
),
|
175
|
+
trace_id="trace_id",
|
176
|
+
span_id="span_id",
|
151
177
|
),
|
152
|
-
|
153
|
-
|
154
|
-
|
178
|
+
NodeExecutionInitiatedEvent(
|
179
|
+
body=NodeExecutionInitiatedBody(
|
180
|
+
node_definition=VellumCodeResourceDefinition(
|
181
|
+
name="name",
|
182
|
+
module=["module", "module"],
|
183
|
+
id="id",
|
184
|
+
),
|
185
|
+
inputs={"inputs": {"key": "value"}},
|
186
|
+
),
|
187
|
+
id="id",
|
188
|
+
timestamp=datetime.datetime.fromisoformat(
|
189
|
+
"2024-01-15 09:30:00+00:00",
|
190
|
+
),
|
191
|
+
trace_id="trace_id",
|
192
|
+
span_id="span_id",
|
155
193
|
),
|
156
|
-
|
157
|
-
span_id="span_id",
|
158
|
-
),
|
194
|
+
],
|
159
195
|
)
|
160
196
|
|
161
197
|
|
@@ -13,9 +13,9 @@ from ...errors.bad_request_error import BadRequestError
|
|
13
13
|
from ...errors.forbidden_error import ForbiddenError
|
14
14
|
from ...errors.too_many_requests_error import TooManyRequestsError
|
15
15
|
from ...errors.unauthorized_error import UnauthorizedError
|
16
|
+
from ...types.create_workflow_event_request import CreateWorkflowEventRequest
|
16
17
|
from ...types.error_detail_response import ErrorDetailResponse
|
17
18
|
from ...types.event_create_response import EventCreateResponse
|
18
|
-
from ...types.workflow_event import WorkflowEvent
|
19
19
|
|
20
20
|
# this is used as the default value for optional parameters
|
21
21
|
OMIT = typing.cast(typing.Any, ...)
|
@@ -26,14 +26,14 @@ class RawEventsClient:
|
|
26
26
|
self._client_wrapper = client_wrapper
|
27
27
|
|
28
28
|
def create(
|
29
|
-
self, *, request:
|
29
|
+
self, *, request: CreateWorkflowEventRequest, request_options: typing.Optional[RequestOptions] = None
|
30
30
|
) -> HttpResponse[EventCreateResponse]:
|
31
31
|
"""
|
32
|
-
Accept an event and publish
|
32
|
+
Accept an event or list of events and publish them to ClickHouse for analytics processing.
|
33
33
|
|
34
34
|
Parameters
|
35
35
|
----------
|
36
|
-
request :
|
36
|
+
request : CreateWorkflowEventRequest
|
37
37
|
|
38
38
|
request_options : typing.Optional[RequestOptions]
|
39
39
|
Request-specific configuration.
|
@@ -47,7 +47,9 @@ class RawEventsClient:
|
|
47
47
|
"monitoring/v1/events",
|
48
48
|
base_url=self._client_wrapper.get_environment().default,
|
49
49
|
method="POST",
|
50
|
-
json=convert_and_respect_annotation_metadata(
|
50
|
+
json=convert_and_respect_annotation_metadata(
|
51
|
+
object_=request, annotation=CreateWorkflowEventRequest, direction="write"
|
52
|
+
),
|
51
53
|
headers={
|
52
54
|
"content-type": "application/json",
|
53
55
|
},
|
@@ -119,14 +121,14 @@ class AsyncRawEventsClient:
|
|
119
121
|
self._client_wrapper = client_wrapper
|
120
122
|
|
121
123
|
async def create(
|
122
|
-
self, *, request:
|
124
|
+
self, *, request: CreateWorkflowEventRequest, request_options: typing.Optional[RequestOptions] = None
|
123
125
|
) -> AsyncHttpResponse[EventCreateResponse]:
|
124
126
|
"""
|
125
|
-
Accept an event and publish
|
127
|
+
Accept an event or list of events and publish them to ClickHouse for analytics processing.
|
126
128
|
|
127
129
|
Parameters
|
128
130
|
----------
|
129
|
-
request :
|
131
|
+
request : CreateWorkflowEventRequest
|
130
132
|
|
131
133
|
request_options : typing.Optional[RequestOptions]
|
132
134
|
Request-specific configuration.
|
@@ -140,7 +142,9 @@ class AsyncRawEventsClient:
|
|
140
142
|
"monitoring/v1/events",
|
141
143
|
base_url=self._client_wrapper.get_environment().default,
|
142
144
|
method="POST",
|
143
|
-
json=convert_and_respect_annotation_metadata(
|
145
|
+
json=convert_and_respect_annotation_metadata(
|
146
|
+
object_=request, annotation=CreateWorkflowEventRequest, direction="write"
|
147
|
+
),
|
144
148
|
headers={
|
145
149
|
"content-type": "application/json",
|
146
150
|
},
|
vellum/client/types/__init__.py
CHANGED
@@ -82,6 +82,7 @@ from .container_image_build_config import ContainerImageBuildConfig
|
|
82
82
|
from .container_image_container_image_tag import ContainerImageContainerImageTag
|
83
83
|
from .container_image_read import ContainerImageRead
|
84
84
|
from .create_test_suite_test_case_request import CreateTestSuiteTestCaseRequest
|
85
|
+
from .create_workflow_event_request import CreateWorkflowEventRequest
|
85
86
|
from .delimiter_chunker_config import DelimiterChunkerConfig
|
86
87
|
from .delimiter_chunker_config_request import DelimiterChunkerConfigRequest
|
87
88
|
from .delimiter_chunking import DelimiterChunking
|
@@ -92,6 +93,7 @@ from .deployment_provider_payload_response_payload import DeploymentProviderPayl
|
|
92
93
|
from .deployment_read import DeploymentRead
|
93
94
|
from .deployment_release_tag_deployment_history_item import DeploymentReleaseTagDeploymentHistoryItem
|
94
95
|
from .deployment_release_tag_read import DeploymentReleaseTagRead
|
96
|
+
from .deprecated_prompt_request_input import DeprecatedPromptRequestInput
|
95
97
|
from .docker_service_token import DockerServiceToken
|
96
98
|
from .document_chat_message_content import DocumentChatMessageContent
|
97
99
|
from .document_chat_message_content_request import DocumentChatMessageContentRequest
|
@@ -648,6 +650,7 @@ from .workflow_execution_view_online_eval_metric_result import WorkflowExecution
|
|
648
650
|
from .workflow_execution_workflow_result_event import WorkflowExecutionWorkflowResultEvent
|
649
651
|
from .workflow_expand_meta_request import WorkflowExpandMetaRequest
|
650
652
|
from .workflow_initialization_error import WorkflowInitializationError
|
653
|
+
from .workflow_input import WorkflowInput
|
651
654
|
from .workflow_node_result_data import WorkflowNodeResultData
|
652
655
|
from .workflow_node_result_event import WorkflowNodeResultEvent
|
653
656
|
from .workflow_node_result_event_state import WorkflowNodeResultEventState
|
@@ -765,6 +768,7 @@ __all__ = [
|
|
765
768
|
"ContainerImageContainerImageTag",
|
766
769
|
"ContainerImageRead",
|
767
770
|
"CreateTestSuiteTestCaseRequest",
|
771
|
+
"CreateWorkflowEventRequest",
|
768
772
|
"DelimiterChunkerConfig",
|
769
773
|
"DelimiterChunkerConfigRequest",
|
770
774
|
"DelimiterChunking",
|
@@ -775,6 +779,7 @@ __all__ = [
|
|
775
779
|
"DeploymentRead",
|
776
780
|
"DeploymentReleaseTagDeploymentHistoryItem",
|
777
781
|
"DeploymentReleaseTagRead",
|
782
|
+
"DeprecatedPromptRequestInput",
|
778
783
|
"DockerServiceToken",
|
779
784
|
"DocumentChatMessageContent",
|
780
785
|
"DocumentChatMessageContentRequest",
|
@@ -1311,6 +1316,7 @@ __all__ = [
|
|
1311
1316
|
"WorkflowExecutionWorkflowResultEvent",
|
1312
1317
|
"WorkflowExpandMetaRequest",
|
1313
1318
|
"WorkflowInitializationError",
|
1319
|
+
"WorkflowInput",
|
1314
1320
|
"WorkflowNodeResultData",
|
1315
1321
|
"WorkflowNodeResultEvent",
|
1316
1322
|
"WorkflowNodeResultEventState",
|
@@ -16,6 +16,11 @@ class EventCreateResponse(UniversalBaseModel):
|
|
16
16
|
Indicates whether the event was published successfully.
|
17
17
|
"""
|
18
18
|
|
19
|
+
count: int = pydantic.Field()
|
20
|
+
"""
|
21
|
+
Number of events processed
|
22
|
+
"""
|
23
|
+
|
19
24
|
if IS_PYDANTIC_V2:
|
20
25
|
model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
|
21
26
|
else:
|
@@ -2,4 +2,6 @@
|
|
2
2
|
|
3
3
|
import typing
|
4
4
|
|
5
|
-
ProcessingFailureReasonEnum = typing.Union[
|
5
|
+
ProcessingFailureReasonEnum = typing.Union[
|
6
|
+
typing.Literal["EXCEEDED_CHARACTER_LIMIT", "INVALID_FILE", "INVALID_CREDENTIALS"], typing.Any
|
7
|
+
]
|
@@ -39,6 +39,7 @@ class SlimDocument(UniversalBaseModel):
|
|
39
39
|
|
40
40
|
* `EXCEEDED_CHARACTER_LIMIT` - Exceeded Character Limit
|
41
41
|
* `INVALID_FILE` - Invalid File
|
42
|
+
* `INVALID_CREDENTIALS` - Invalid Credentials
|
42
43
|
"""
|
43
44
|
|
44
45
|
status: typing.Optional[DocumentStatus] = pydantic.Field(default=None)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
2
|
+
|
3
|
+
import typing
|
4
|
+
|
5
|
+
from .array_input import ArrayInput
|
6
|
+
from .audio_input import AudioInput
|
7
|
+
from .chat_history_input import ChatHistoryInput
|
8
|
+
from .document_input import DocumentInput
|
9
|
+
from .error_input import ErrorInput
|
10
|
+
from .function_call_input import FunctionCallInput
|
11
|
+
from .image_input import ImageInput
|
12
|
+
from .json_input import JsonInput
|
13
|
+
from .number_input import NumberInput
|
14
|
+
from .search_results_input import SearchResultsInput
|
15
|
+
from .string_input import StringInput
|
16
|
+
from .video_input import VideoInput
|
17
|
+
|
18
|
+
WorkflowInput = typing.Union[
|
19
|
+
StringInput,
|
20
|
+
JsonInput,
|
21
|
+
ChatHistoryInput,
|
22
|
+
NumberInput,
|
23
|
+
SearchResultsInput,
|
24
|
+
ErrorInput,
|
25
|
+
ArrayInput,
|
26
|
+
FunctionCallInput,
|
27
|
+
AudioInput,
|
28
|
+
VideoInput,
|
29
|
+
ImageInput,
|
30
|
+
DocumentInput,
|
31
|
+
]
|
vellum/workflows/constants.py
CHANGED
vellum/workflows/events/node.py
CHANGED
@@ -141,6 +141,7 @@ class NodeExecutionFulfilledEvent(_BaseNodeEvent, Generic[OutputsType]):
|
|
141
141
|
|
142
142
|
class NodeExecutionRejectedBody(_BaseNodeExecutionBody):
|
143
143
|
error: WorkflowError
|
144
|
+
traceback: Optional[str] = None
|
144
145
|
|
145
146
|
|
146
147
|
class NodeExecutionRejectedEvent(_BaseNodeEvent):
|
@@ -156,6 +156,7 @@ class WorkflowExecutionFulfilledEvent(_BaseWorkflowEvent, Generic[OutputsType]):
|
|
156
156
|
|
157
157
|
class WorkflowExecutionRejectedBody(_BaseWorkflowExecutionBody):
|
158
158
|
error: WorkflowError
|
159
|
+
traceback: Optional[str] = None
|
159
160
|
|
160
161
|
|
161
162
|
class WorkflowExecutionRejectedEvent(_BaseWorkflowEvent):
|
@@ -446,3 +446,19 @@ def test_templating_node__conditional_type_checking():
|
|
446
446
|
|
447
447
|
# THEN conditional type checking works
|
448
448
|
assert outputs.result == "test string"
|
449
|
+
|
450
|
+
|
451
|
+
def test_templating_node__dict_wrapper_nonexistent_attribute_is_none():
|
452
|
+
"""Test that non-existent attributes on DictWrapper evaluate to None."""
|
453
|
+
|
454
|
+
# GIVEN a templating node with nonexistent attr in the template
|
455
|
+
class TemplateNode(TemplatingNode[BaseState, str]):
|
456
|
+
template = "{% if data.nonexistent_attr is none %}none_value{% else %}{{ data.nonexistent_attr }}{% endif %}"
|
457
|
+
inputs = {"data": {"existing_key": "existing_value"}}
|
458
|
+
|
459
|
+
# WHEN the node is run
|
460
|
+
node = TemplateNode()
|
461
|
+
outputs = node.run()
|
462
|
+
|
463
|
+
# THEN it should recognize the non-existent attribute as ""
|
464
|
+
assert outputs.result == ""
|
@@ -847,21 +847,11 @@ def main(arg1: list) -> str:
|
|
847
847
|
runtime = "PYTHON_3_11_6"
|
848
848
|
|
849
849
|
# WHEN we run the node
|
850
|
-
|
851
|
-
|
852
|
-
node.run()
|
850
|
+
node = ExampleCodeExecutionNode()
|
851
|
+
outputs = node.run()
|
853
852
|
|
854
853
|
# AND the result should be the correct output
|
855
|
-
assert
|
856
|
-
exc_info.value.message
|
857
|
-
== """\
|
858
|
-
Traceback (most recent call last):
|
859
|
-
File "ExampleCodeExecutionNode.code.py", line 2, in main
|
860
|
-
return arg1["invalid"]
|
861
|
-
|
862
|
-
AttributeError: dict has no key: 'invalid'
|
863
|
-
"""
|
864
|
-
)
|
854
|
+
assert outputs == {"result": "", "log": ""}
|
865
855
|
|
866
856
|
|
867
857
|
def test_run_node__execute_code__value_key_access():
|
@@ -150,3 +150,26 @@ def test_cast_to_output_type_none_value(output_type, expected_result):
|
|
150
150
|
"""Test that cast_to_output_type returns appropriate default values when None is provided."""
|
151
151
|
result = cast_to_output_type(None, output_type)
|
152
152
|
assert result == expected_result
|
153
|
+
|
154
|
+
|
155
|
+
@pytest.mark.parametrize(
|
156
|
+
"input_value,expected_result",
|
157
|
+
[
|
158
|
+
('{"name": "Alice", "age": 30}', {"name": "Alice", "age": 30}),
|
159
|
+
("[1, 2, 3]", [1, 2, 3]),
|
160
|
+
("invalid json", "invalid json"),
|
161
|
+
([1, 2, 3], [1, 2, 3]),
|
162
|
+
({"already": "dict"}, {"already": "dict"}),
|
163
|
+
],
|
164
|
+
ids=[
|
165
|
+
"valid_json_object",
|
166
|
+
"valid_json_array",
|
167
|
+
"invalid_json_string",
|
168
|
+
"non_string_list",
|
169
|
+
"non_string_dict",
|
170
|
+
],
|
171
|
+
)
|
172
|
+
def test_cast_to_output_type_any_json_parsing(input_value, expected_result):
|
173
|
+
"""Test that cast_to_output_type attempts JSON parsing for Any type and falls back gracefully."""
|
174
|
+
result = cast_to_output_type(input_value, Any)
|
175
|
+
assert result == expected_result
|
vellum/workflows/nodes/utils.py
CHANGED
@@ -8,6 +8,7 @@ from typing import Any, Callable, Dict, ForwardRef, List, Optional, Type, TypeVa
|
|
8
8
|
from pydantic import BaseModel, create_model
|
9
9
|
|
10
10
|
from vellum.client.types.function_call import FunctionCall
|
11
|
+
from vellum.workflows.constants import undefined
|
11
12
|
from vellum.workflows.errors.types import WorkflowErrorCode
|
12
13
|
from vellum.workflows.exceptions import NodeException
|
13
14
|
from vellum.workflows.inputs.base import BaseInputs
|
@@ -253,6 +254,19 @@ def cast_to_output_type(result: Any, output_type: Any) -> Any:
|
|
253
254
|
if result is None:
|
254
255
|
return _get_default_value(output_type)
|
255
256
|
|
257
|
+
if result is undefined:
|
258
|
+
return _get_default_value(output_type)
|
259
|
+
|
260
|
+
# Attempt JSON parse if type is Any
|
261
|
+
if output_type is Any:
|
262
|
+
if isinstance(result, str):
|
263
|
+
try:
|
264
|
+
return json.loads(result)
|
265
|
+
except (json.JSONDecodeError, TypeError):
|
266
|
+
# If JSON parsing fails, fall back to original result
|
267
|
+
pass
|
268
|
+
return result
|
269
|
+
|
256
270
|
clean_output_type = _clean_output_type(output_type)
|
257
271
|
DynamicModel = create_model("Output", output_type=(clean_output_type, ...))
|
258
272
|
|