vellum-ai 1.3.1__py3-none-any.whl → 1.3.3__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 (49) hide show
  1. vellum/__init__.py +6 -0
  2. vellum/client/README.md +5 -5
  3. vellum/client/__init__.py +20 -0
  4. vellum/client/core/client_wrapper.py +2 -2
  5. vellum/client/raw_client.py +20 -0
  6. vellum/client/reference.md +61 -27
  7. vellum/client/resources/ad_hoc/client.py +29 -29
  8. vellum/client/resources/ad_hoc/raw_client.py +13 -13
  9. vellum/client/resources/events/client.py +69 -33
  10. vellum/client/resources/events/raw_client.py +13 -9
  11. vellum/client/types/__init__.py +6 -0
  12. vellum/client/types/create_workflow_event_request.py +7 -0
  13. vellum/client/types/deprecated_prompt_request_input.py +8 -0
  14. vellum/client/types/event_create_response.py +5 -0
  15. vellum/client/types/logical_operator.py +1 -0
  16. vellum/client/types/processing_failure_reason_enum.py +3 -1
  17. vellum/client/types/slim_document.py +1 -0
  18. vellum/client/types/workflow_input.py +31 -0
  19. vellum/types/create_workflow_event_request.py +3 -0
  20. vellum/types/deprecated_prompt_request_input.py +3 -0
  21. vellum/types/workflow_input.py +3 -0
  22. vellum/workflows/constants.py +3 -0
  23. vellum/workflows/emitters/vellum_emitter.py +55 -9
  24. vellum/workflows/events/node.py +1 -0
  25. vellum/workflows/events/tests/test_event.py +1 -0
  26. vellum/workflows/events/workflow.py +1 -0
  27. vellum/workflows/nodes/core/retry_node/tests/test_node.py +1 -2
  28. vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py +16 -0
  29. vellum/workflows/nodes/displayable/code_execution_node/tests/test_node.py +3 -13
  30. vellum/workflows/nodes/displayable/tool_calling_node/utils.py +6 -13
  31. vellum/workflows/nodes/tests/test_utils.py +23 -0
  32. vellum/workflows/nodes/utils.py +14 -0
  33. vellum/workflows/runner/runner.py +33 -12
  34. vellum/workflows/state/tests/test_state.py +14 -0
  35. vellum/workflows/types/code_execution_node_wrappers.py +5 -1
  36. vellum/workflows/utils/vellum_variables.py +11 -2
  37. {vellum_ai-1.3.1.dist-info → vellum_ai-1.3.3.dist-info}/METADATA +1 -1
  38. {vellum_ai-1.3.1.dist-info → vellum_ai-1.3.3.dist-info}/RECORD +49 -40
  39. vellum_cli/__init__.py +21 -0
  40. vellum_cli/move.py +56 -0
  41. vellum_cli/tests/test_move.py +154 -0
  42. vellum_ee/workflows/display/base.py +1 -0
  43. vellum_ee/workflows/display/editor/types.py +1 -0
  44. vellum_ee/workflows/display/nodes/base_node_display.py +1 -0
  45. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_prompt_node_serialization.py +16 -5
  46. vellum_ee/workflows/display/tests/workflow_serialization/test_web_search_node_serialization.py +81 -0
  47. {vellum_ai-1.3.1.dist-info → vellum_ai-1.3.3.dist-info}/LICENSE +0 -0
  48. {vellum_ai-1.3.1.dist-info → vellum_ai-1.3.3.dist-info}/WHEEL +0 -0
  49. {vellum_ai-1.3.1.dist-info → vellum_ai-1.3.3.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[PromptRequestInput],
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[PromptRequestInput]
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[PromptRequestInput], direction="write"
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[PromptRequestInput],
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[PromptRequestInput]
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[PromptRequestInput], direction="write"
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[PromptRequestInput],
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[PromptRequestInput]
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[PromptRequestInput], direction="write"
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[PromptRequestInput],
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[PromptRequestInput]
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[PromptRequestInput], direction="write"
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: WorkflowEvent, request_options: typing.Optional[RequestOptions] = None
35
+ self, *, request: CreateWorkflowEventRequest, request_options: typing.Optional[RequestOptions] = None
36
36
  ) -> EventCreateResponse:
37
37
  """
38
- Accept an event and publish it to ClickHouse for analytics processing.
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 : WorkflowEvent
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=NodeExecutionInitiatedEvent(
69
- body=NodeExecutionInitiatedBody(
70
- node_definition=VellumCodeResourceDefinition(
71
- name="name",
72
- module=["module", "module"],
73
- id="id",
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
- inputs={"inputs": {"key": "value"}},
82
+ trace_id="trace_id",
83
+ span_id="span_id",
76
84
  ),
77
- id="id",
78
- timestamp=datetime.datetime.fromisoformat(
79
- "2024-01-15 09:30:00+00:00",
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
- trace_id="trace_id",
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: WorkflowEvent, request_options: typing.Optional[RequestOptions] = None
124
+ self, *, request: CreateWorkflowEventRequest, request_options: typing.Optional[RequestOptions] = None
107
125
  ) -> EventCreateResponse:
108
126
  """
109
- Accept an event and publish it to ClickHouse for analytics processing.
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 : WorkflowEvent
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=NodeExecutionInitiatedEvent(
144
- body=NodeExecutionInitiatedBody(
145
- node_definition=VellumCodeResourceDefinition(
146
- name="name",
147
- module=["module", "module"],
148
- id="id",
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
- inputs={"inputs": {"key": "value"}},
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
- id="id",
153
- timestamp=datetime.datetime.fromisoformat(
154
- "2024-01-15 09:30:00+00:00",
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
- trace_id="trace_id",
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: WorkflowEvent, request_options: typing.Optional[RequestOptions] = None
29
+ self, *, request: CreateWorkflowEventRequest, request_options: typing.Optional[RequestOptions] = None
30
30
  ) -> HttpResponse[EventCreateResponse]:
31
31
  """
32
- Accept an event and publish it to ClickHouse for analytics processing.
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 : WorkflowEvent
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(object_=request, annotation=WorkflowEvent, direction="write"),
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: WorkflowEvent, request_options: typing.Optional[RequestOptions] = None
124
+ self, *, request: CreateWorkflowEventRequest, request_options: typing.Optional[RequestOptions] = None
123
125
  ) -> AsyncHttpResponse[EventCreateResponse]:
124
126
  """
125
- Accept an event and publish it to ClickHouse for analytics processing.
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 : WorkflowEvent
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(object_=request, annotation=WorkflowEvent, direction="write"),
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
  },
@@ -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",
@@ -0,0 +1,7 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from .workflow_event import WorkflowEvent
6
+
7
+ CreateWorkflowEventRequest = typing.Union[typing.List[WorkflowEvent], WorkflowEvent]
@@ -0,0 +1,8 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from .prompt_request_input import PromptRequestInput
6
+ from .workflow_input import WorkflowInput
7
+
8
+ DeprecatedPromptRequestInput = typing.Union[WorkflowInput, PromptRequestInput]
@@ -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:
@@ -22,6 +22,7 @@ LogicalOperator = typing.Union[
22
22
  "notIn",
23
23
  "between",
24
24
  "notBetween",
25
+ "concat",
25
26
  "blank",
26
27
  "notBlank",
27
28
  "coalesce",
@@ -2,4 +2,6 @@
2
2
 
3
3
  import typing
4
4
 
5
- ProcessingFailureReasonEnum = typing.Union[typing.Literal["EXCEEDED_CHARACTER_LIMIT", "INVALID_FILE"], typing.Any]
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
+ ]
@@ -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.create_workflow_event_request 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.deprecated_prompt_request_input 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_input import *
@@ -22,6 +22,9 @@ class _UndefMeta(type):
22
22
 
23
23
  return super().__getattribute__(name)
24
24
 
25
+ def __str__(cls) -> str:
26
+ return ""
27
+
25
28
  def __bool__(cls) -> bool:
26
29
  return False
27
30
 
@@ -1,5 +1,6 @@
1
1
  import logging
2
- from typing import Optional
2
+ import threading
3
+ from typing import List, Optional
3
4
 
4
5
  from vellum.core.request_options import RequestOptions
5
6
  from vellum.workflows.emitters.base import BaseWorkflowEmitter
@@ -29,6 +30,7 @@ class VellumEmitter(BaseWorkflowEmitter):
29
30
  *,
30
31
  timeout: Optional[float] = 30.0,
31
32
  max_retries: int = 3,
33
+ debounce_timeout: float = 0.1,
32
34
  ):
33
35
  """
34
36
  Initialize the VellumEmitter.
@@ -36,14 +38,19 @@ class VellumEmitter(BaseWorkflowEmitter):
36
38
  Args:
37
39
  timeout: Request timeout in seconds.
38
40
  max_retries: Maximum number of retry attempts for failed requests.
41
+ debounce_timeout: Time in seconds to wait before sending batched events.
39
42
  """
40
43
  super().__init__()
41
44
  self._timeout = timeout
42
45
  self._max_retries = max_retries
46
+ self._debounce_timeout = debounce_timeout
47
+ self._event_queue: List[SDKWorkflowEvent] = []
48
+ self._queue_lock = threading.Lock()
49
+ self._debounce_timer: Optional[threading.Timer] = None
43
50
 
44
51
  def emit_event(self, event: SDKWorkflowEvent) -> None:
45
52
  """
46
- Emit a workflow event to Vellum's infrastructure.
53
+ Queue a workflow event for batched emission to Vellum's infrastructure.
47
54
 
48
55
  Args:
49
56
  event: The workflow event to emit.
@@ -55,10 +62,45 @@ class VellumEmitter(BaseWorkflowEmitter):
55
62
  return
56
63
 
57
64
  try:
58
- self._send_event(event)
65
+ with self._queue_lock:
66
+ self._event_queue.append(event)
59
67
 
68
+ if self._debounce_timer:
69
+ self._debounce_timer.cancel()
70
+
71
+ self._debounce_timer = threading.Timer(self._debounce_timeout, self._flush_events)
72
+ self._debounce_timer.start()
73
+
74
+ except Exception as e:
75
+ logger.exception(f"Failed to queue event {event.name}: {e}")
76
+
77
+ def _flush_events(self) -> None:
78
+ """
79
+ Send all queued events as a batch to Vellum's infrastructure.
80
+ """
81
+ with self._queue_lock:
82
+ if not self._event_queue:
83
+ return
84
+
85
+ events_to_send = self._event_queue.copy()
86
+ self._event_queue.clear()
87
+ self._debounce_timer = None
88
+
89
+ try:
90
+ self._send_events(events_to_send)
60
91
  except Exception as e:
61
- logger.exception(f"Failed to emit event {event.name}: {e}")
92
+ logger.exception(f"Failed to send batched events: {e}")
93
+
94
+ def __del__(self) -> None:
95
+ """
96
+ Cleanup: flush any pending events and cancel timer.
97
+ """
98
+ try:
99
+ if self._debounce_timer:
100
+ self._debounce_timer.cancel()
101
+ self._flush_events()
102
+ except Exception:
103
+ pass
62
104
 
63
105
  def snapshot_state(self, state: BaseState) -> None:
64
106
  """
@@ -69,23 +111,27 @@ class VellumEmitter(BaseWorkflowEmitter):
69
111
  """
70
112
  pass
71
113
 
72
- def _send_event(self, event: SDKWorkflowEvent) -> None:
114
+ def _send_events(self, events: List[SDKWorkflowEvent]) -> None:
73
115
  """
74
- Send event to Vellum's events endpoint using client.events.create.
116
+ Send events to Vellum's events endpoint using client.events.create.
75
117
 
76
118
  Args:
77
- event: The WorkflowEvent object to send.
119
+ events: List of WorkflowEvent objects to send.
78
120
  """
79
121
  if not self._context:
80
- logger.warning("Cannot send event: No workflow context registered")
122
+ logger.warning("Cannot send events: No workflow context registered")
123
+ return
124
+
125
+ if not events:
81
126
  return
82
127
 
83
128
  client = self._context.vellum_client
84
129
  request_options = RequestOptions(timeout_in_seconds=self._timeout, max_retries=self._max_retries)
130
+
85
131
  client.events.create(
86
132
  # The API accepts a ClientWorkflowEvent but our SDK emits an SDKWorkflowEvent. These shapes are
87
133
  # meant to be identical, just with different helper methods. We may consolidate the two in the future.
88
134
  # But for now, the type ignore allows us to avoid an additional Model -> json -> Model conversion.
89
- request=event, # type: ignore[arg-type]
135
+ request=events, # type: ignore[arg-type]
90
136
  request_options=request_options,
91
137
  )
@@ -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):
@@ -261,6 +261,7 @@ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__))
261
261
  "message": "Workflow failed",
262
262
  "code": "USER_DEFINED_ERROR",
263
263
  },
264
+ "traceback": None,
264
265
  },
265
266
  "parent": None,
266
267
  "links": None,
@@ -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):
@@ -6,7 +6,6 @@ from vellum.workflows.inputs.base import BaseInputs
6
6
  from vellum.workflows.nodes.bases import BaseNode
7
7
  from vellum.workflows.nodes.core.retry_node.node import RetryNode
8
8
  from vellum.workflows.outputs import BaseOutputs
9
- from vellum.workflows.references.lazy import LazyReference
10
9
  from vellum.workflows.state.base import BaseState, StateMeta
11
10
 
12
11
 
@@ -102,7 +101,7 @@ def test_retry_node__condition_arg_successfully_retries():
102
101
  # AND a retry node that retries on a condition
103
102
  @RetryNode.wrap(
104
103
  max_attempts=5,
105
- retry_on_condition=LazyReference(lambda: State.count.less_than(3)),
104
+ retry_on_condition=State.count.less_than(3),
106
105
  )
107
106
  class TestNode(BaseNode[State]):
108
107
  attempt_number = RetryNode.SubworkflowInputs.attempt_number