vellum-ai 1.11.2__py3-none-any.whl → 1.13.5__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.

Potentially problematic release.


This version of vellum-ai might be problematic. Click here for more details.

Files changed (275) hide show
  1. vellum/__init__.py +18 -0
  2. vellum/client/README.md +1 -1
  3. vellum/client/core/client_wrapper.py +2 -2
  4. vellum/client/core/force_multipart.py +4 -2
  5. vellum/client/core/http_response.py +1 -1
  6. vellum/client/core/pydantic_utilities.py +7 -4
  7. vellum/client/errors/too_many_requests_error.py +1 -2
  8. vellum/client/reference.md +677 -76
  9. vellum/client/resources/container_images/client.py +299 -0
  10. vellum/client/resources/container_images/raw_client.py +286 -0
  11. vellum/client/resources/documents/client.py +20 -10
  12. vellum/client/resources/documents/raw_client.py +20 -10
  13. vellum/client/resources/events/raw_client.py +4 -4
  14. vellum/client/resources/integration_auth_configs/client.py +2 -0
  15. vellum/client/resources/integration_auth_configs/raw_client.py +2 -0
  16. vellum/client/resources/integration_providers/client.py +28 -2
  17. vellum/client/resources/integration_providers/raw_client.py +24 -0
  18. vellum/client/resources/integrations/client.py +52 -4
  19. vellum/client/resources/integrations/raw_client.py +61 -0
  20. vellum/client/resources/workflow_deployments/client.py +156 -0
  21. vellum/client/resources/workflow_deployments/raw_client.py +334 -0
  22. vellum/client/resources/workflows/client.py +212 -8
  23. vellum/client/resources/workflows/raw_client.py +343 -6
  24. vellum/client/types/__init__.py +18 -0
  25. vellum/client/types/api_actor_type_enum.py +1 -1
  26. vellum/client/types/check_workflow_execution_status_error.py +21 -0
  27. vellum/client/types/check_workflow_execution_status_response.py +29 -0
  28. vellum/client/types/code_execution_package_request.py +21 -0
  29. vellum/client/types/composio_execute_tool_request.py +5 -0
  30. vellum/client/types/composio_tool_definition.py +1 -0
  31. vellum/client/types/container_image_build_config.py +1 -0
  32. vellum/client/types/container_image_container_image_tag.py +1 -0
  33. vellum/client/types/dataset_row_push_request.py +3 -0
  34. vellum/client/types/document_document_to_document_index.py +1 -0
  35. vellum/client/types/integration_name.py +24 -0
  36. vellum/client/types/node_execution_fulfilled_body.py +1 -0
  37. vellum/client/types/node_execution_log_body.py +24 -0
  38. vellum/client/types/node_execution_log_event.py +47 -0
  39. vellum/client/types/prompt_deployment_release_prompt_deployment.py +1 -0
  40. vellum/client/types/runner_config_request.py +24 -0
  41. vellum/client/types/severity_enum.py +5 -0
  42. vellum/client/types/slim_composio_tool_definition.py +1 -0
  43. vellum/client/types/slim_document_document_to_document_index.py +2 -0
  44. vellum/client/types/type_checker_enum.py +5 -0
  45. vellum/client/types/vellum_audio.py +5 -1
  46. vellum/client/types/vellum_audio_request.py +5 -1
  47. vellum/client/types/vellum_document.py +5 -1
  48. vellum/client/types/vellum_document_request.py +5 -1
  49. vellum/client/types/vellum_image.py +5 -1
  50. vellum/client/types/vellum_image_request.py +5 -1
  51. vellum/client/types/vellum_node_execution_event.py +2 -0
  52. vellum/client/types/vellum_variable.py +5 -0
  53. vellum/client/types/vellum_variable_extensions.py +1 -0
  54. vellum/client/types/vellum_variable_type.py +1 -0
  55. vellum/client/types/vellum_video.py +5 -1
  56. vellum/client/types/vellum_video_request.py +5 -1
  57. vellum/client/types/workflow_deployment_release_workflow_deployment.py +1 -0
  58. vellum/client/types/workflow_event.py +2 -0
  59. vellum/client/types/workflow_execution_fulfilled_body.py +1 -0
  60. vellum/client/types/workflow_result_event_output_data_array.py +1 -1
  61. vellum/client/types/workflow_result_event_output_data_chat_history.py +1 -1
  62. vellum/client/types/workflow_result_event_output_data_error.py +1 -1
  63. vellum/client/types/workflow_result_event_output_data_function_call.py +1 -1
  64. vellum/client/types/workflow_result_event_output_data_json.py +1 -1
  65. vellum/client/types/workflow_result_event_output_data_number.py +1 -1
  66. vellum/client/types/workflow_result_event_output_data_search_results.py +1 -1
  67. vellum/client/types/workflow_result_event_output_data_string.py +1 -1
  68. vellum/client/types/workflow_sandbox_execute_node_response.py +8 -0
  69. vellum/plugins/vellum_mypy.py +37 -2
  70. vellum/types/check_workflow_execution_status_error.py +3 -0
  71. vellum/types/check_workflow_execution_status_response.py +3 -0
  72. vellum/types/code_execution_package_request.py +3 -0
  73. vellum/types/node_execution_log_body.py +3 -0
  74. vellum/types/node_execution_log_event.py +3 -0
  75. vellum/types/runner_config_request.py +3 -0
  76. vellum/types/severity_enum.py +3 -0
  77. vellum/types/type_checker_enum.py +3 -0
  78. vellum/types/workflow_sandbox_execute_node_response.py +3 -0
  79. vellum/utils/files/mixin.py +26 -0
  80. vellum/utils/files/tests/test_mixin.py +62 -0
  81. vellum/utils/tests/test_vellum_client.py +95 -0
  82. vellum/utils/uuid.py +19 -2
  83. vellum/utils/vellum_client.py +10 -3
  84. vellum/workflows/__init__.py +7 -1
  85. vellum/workflows/descriptors/base.py +86 -0
  86. vellum/workflows/descriptors/tests/test_utils.py +9 -0
  87. vellum/workflows/errors/tests/__init__.py +0 -0
  88. vellum/workflows/errors/tests/test_types.py +52 -0
  89. vellum/workflows/errors/types.py +1 -0
  90. vellum/workflows/events/node.py +24 -0
  91. vellum/workflows/events/tests/test_event.py +123 -0
  92. vellum/workflows/events/types.py +2 -1
  93. vellum/workflows/events/workflow.py +28 -2
  94. vellum/workflows/expressions/add.py +3 -0
  95. vellum/workflows/expressions/tests/test_add.py +24 -0
  96. vellum/workflows/graph/graph.py +26 -5
  97. vellum/workflows/graph/tests/test_graph.py +228 -1
  98. vellum/workflows/inputs/base.py +22 -6
  99. vellum/workflows/inputs/dataset_row.py +121 -16
  100. vellum/workflows/inputs/tests/test_inputs.py +3 -3
  101. vellum/workflows/integrations/tests/test_vellum_integration_service.py +84 -0
  102. vellum/workflows/integrations/vellum_integration_service.py +12 -1
  103. vellum/workflows/loaders/base.py +2 -0
  104. vellum/workflows/nodes/bases/base.py +37 -16
  105. vellum/workflows/nodes/bases/tests/test_base_node.py +104 -1
  106. vellum/workflows/nodes/core/inline_subworkflow_node/node.py +1 -0
  107. vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py +1 -1
  108. vellum/workflows/nodes/core/map_node/node.py +7 -5
  109. vellum/workflows/nodes/core/map_node/tests/test_node.py +33 -0
  110. vellum/workflows/nodes/core/retry_node/node.py +1 -0
  111. vellum/workflows/nodes/core/try_node/node.py +1 -0
  112. vellum/workflows/nodes/displayable/api_node/node.py +3 -2
  113. vellum/workflows/nodes/displayable/api_node/tests/test_api_node.py +38 -0
  114. vellum/workflows/nodes/displayable/bases/api_node/node.py +1 -1
  115. vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +18 -1
  116. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +109 -2
  117. vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py +13 -2
  118. vellum/workflows/nodes/displayable/code_execution_node/node.py +9 -15
  119. vellum/workflows/nodes/displayable/code_execution_node/tests/test_node.py +65 -24
  120. vellum/workflows/nodes/displayable/code_execution_node/utils.py +3 -0
  121. vellum/workflows/nodes/displayable/final_output_node/node.py +24 -69
  122. vellum/workflows/nodes/displayable/final_output_node/tests/test_node.py +53 -3
  123. vellum/workflows/nodes/displayable/note_node/node.py +4 -1
  124. vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +16 -5
  125. vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +47 -0
  126. vellum/workflows/nodes/displayable/tool_calling_node/node.py +74 -34
  127. vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py +204 -8
  128. vellum/workflows/nodes/displayable/tool_calling_node/utils.py +92 -71
  129. vellum/workflows/nodes/mocks.py +47 -213
  130. vellum/workflows/nodes/tests/test_mocks.py +0 -177
  131. vellum/workflows/nodes/utils.py +23 -8
  132. vellum/workflows/outputs/base.py +36 -3
  133. vellum/workflows/references/environment_variable.py +1 -11
  134. vellum/workflows/references/lazy.py +8 -0
  135. vellum/workflows/references/state_value.py +24 -1
  136. vellum/workflows/references/tests/test_lazy.py +58 -0
  137. vellum/workflows/references/trigger.py +8 -3
  138. vellum/workflows/references/workflow_input.py +8 -0
  139. vellum/workflows/resolvers/resolver.py +13 -3
  140. vellum/workflows/resolvers/tests/test_resolver.py +31 -0
  141. vellum/workflows/runner/runner.py +159 -14
  142. vellum/workflows/runner/tests/__init__.py +0 -0
  143. vellum/workflows/runner/tests/test_runner.py +170 -0
  144. vellum/workflows/sandbox.py +7 -8
  145. vellum/workflows/state/base.py +89 -30
  146. vellum/workflows/state/context.py +74 -3
  147. vellum/workflows/state/tests/test_state.py +269 -1
  148. vellum/workflows/tests/test_dataset_row.py +8 -7
  149. vellum/workflows/tests/test_sandbox.py +97 -8
  150. vellum/workflows/triggers/__init__.py +2 -1
  151. vellum/workflows/triggers/base.py +160 -28
  152. vellum/workflows/triggers/chat_message.py +141 -0
  153. vellum/workflows/triggers/integration.py +12 -0
  154. vellum/workflows/triggers/manual.py +3 -1
  155. vellum/workflows/triggers/schedule.py +3 -1
  156. vellum/workflows/triggers/tests/test_chat_message.py +257 -0
  157. vellum/workflows/types/core.py +18 -0
  158. vellum/workflows/types/definition.py +6 -13
  159. vellum/workflows/types/generics.py +12 -0
  160. vellum/workflows/types/tests/test_utils.py +12 -0
  161. vellum/workflows/types/utils.py +32 -2
  162. vellum/workflows/types/workflow_metadata.py +124 -0
  163. vellum/workflows/utils/functions.py +152 -16
  164. vellum/workflows/utils/pydantic_schema.py +19 -1
  165. vellum/workflows/utils/tests/test_functions.py +123 -8
  166. vellum/workflows/utils/tests/test_validate.py +79 -0
  167. vellum/workflows/utils/tests/test_vellum_variables.py +62 -2
  168. vellum/workflows/utils/uuids.py +90 -0
  169. vellum/workflows/utils/validate.py +108 -0
  170. vellum/workflows/utils/vellum_variables.py +96 -16
  171. vellum/workflows/workflows/base.py +177 -35
  172. vellum/workflows/workflows/tests/test_base_workflow.py +51 -0
  173. {vellum_ai-1.11.2.dist-info → vellum_ai-1.13.5.dist-info}/METADATA +6 -1
  174. {vellum_ai-1.11.2.dist-info → vellum_ai-1.13.5.dist-info}/RECORD +274 -227
  175. vellum_cli/__init__.py +21 -0
  176. vellum_cli/config.py +16 -2
  177. vellum_cli/pull.py +2 -0
  178. vellum_cli/push.py +23 -10
  179. vellum_cli/tests/conftest.py +8 -13
  180. vellum_cli/tests/test_image_push.py +4 -11
  181. vellum_cli/tests/test_pull.py +83 -68
  182. vellum_cli/tests/test_push.py +251 -2
  183. vellum_ee/assets/node-definitions.json +225 -12
  184. vellum_ee/scripts/generate_node_definitions.py +15 -3
  185. vellum_ee/workflows/display/base.py +4 -3
  186. vellum_ee/workflows/display/nodes/base_node_display.py +44 -11
  187. vellum_ee/workflows/display/nodes/tests/test_base_node_display.py +93 -0
  188. vellum_ee/workflows/display/nodes/types.py +1 -0
  189. vellum_ee/workflows/display/nodes/vellum/__init__.py +0 -2
  190. vellum_ee/workflows/display/nodes/vellum/base_adornment_node.py +5 -2
  191. vellum_ee/workflows/display/nodes/vellum/code_execution_node.py +1 -1
  192. vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +10 -2
  193. vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py +17 -14
  194. vellum_ee/workflows/display/nodes/vellum/map_node.py +2 -0
  195. vellum_ee/workflows/display/nodes/vellum/note_node.py +18 -3
  196. vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py +37 -14
  197. vellum_ee/workflows/display/nodes/vellum/tests/test_code_execution_node.py +62 -2
  198. vellum_ee/workflows/display/nodes/vellum/tests/test_final_output_node.py +136 -0
  199. vellum_ee/workflows/display/nodes/vellum/tests/test_note_node.py +44 -7
  200. vellum_ee/workflows/display/nodes/vellum/tests/test_prompt_node.py +5 -13
  201. vellum_ee/workflows/display/nodes/vellum/tests/test_subworkflow_deployment_node.py +27 -17
  202. vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py +145 -22
  203. vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +107 -2
  204. vellum_ee/workflows/display/nodes/vellum/utils.py +54 -12
  205. vellum_ee/workflows/display/tests/test_base_workflow_display.py +13 -16
  206. vellum_ee/workflows/display/tests/test_json_schema_validation.py +190 -0
  207. vellum_ee/workflows/display/tests/test_mocks.py +912 -0
  208. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +14 -2
  209. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +109 -0
  210. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_outputs_serialization.py +3 -0
  211. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_ports_serialization.py +187 -1
  212. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +34 -325
  213. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +42 -393
  214. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +13 -315
  215. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_default_state_serialization.py +2 -122
  216. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_error_node_serialization.py +24 -115
  217. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_generic_node_serialization.py +4 -93
  218. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_guardrail_node_serialization.py +7 -80
  219. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_prompt_node_serialization.py +9 -101
  220. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +77 -308
  221. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +62 -324
  222. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +3 -82
  223. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_prompt_deployment_serialization.py +4 -142
  224. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_search_node_serialization.py +1 -61
  225. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_set_state_node_serialization.py +4 -4
  226. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_deployment_serialization.py +205 -134
  227. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py +34 -146
  228. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py +2 -0
  229. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_composio_serialization.py +8 -6
  230. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py +137 -266
  231. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_tool_wrapper_serialization.py +84 -0
  232. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_mcp_serialization.py +55 -16
  233. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py +15 -1
  234. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_tool_wrapper_serialization.py +71 -0
  235. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_vellum_integration_serialization.py +119 -0
  236. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_workflow_deployment_serialization.py +1 -1
  237. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py +0 -2
  238. vellum_ee/workflows/display/tests/workflow_serialization/test_chat_message_dict_reference_serialization.py +22 -1
  239. vellum_ee/workflows/display/tests/workflow_serialization/test_chat_message_trigger_serialization.py +412 -0
  240. vellum_ee/workflows/display/tests/workflow_serialization/test_code_tool_node_reference_error.py +106 -0
  241. vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py +9 -41
  242. vellum_ee/workflows/display/tests/workflow_serialization/test_duplicate_trigger_name_validation.py +208 -0
  243. vellum_ee/workflows/display/tests/workflow_serialization/test_final_output_node_not_referenced_by_workflow_outputs.py +45 -0
  244. vellum_ee/workflows/display/tests/workflow_serialization/test_infinite_loop_validation.py +66 -0
  245. vellum_ee/workflows/display/tests/workflow_serialization/test_int_input_serialization.py +40 -0
  246. vellum_ee/workflows/display/tests/workflow_serialization/test_integration_trigger_serialization.py +8 -14
  247. vellum_ee/workflows/display/tests/workflow_serialization/test_integration_trigger_validation.py +173 -0
  248. vellum_ee/workflows/display/tests/workflow_serialization/test_integration_trigger_with_entrypoint_node_id.py +16 -13
  249. vellum_ee/workflows/display/tests/workflow_serialization/test_list_vellum_document_serialization.py +5 -1
  250. vellum_ee/workflows/display/tests/workflow_serialization/test_manual_trigger_serialization.py +12 -2
  251. vellum_ee/workflows/display/tests/workflow_serialization/test_multi_trigger_same_node_serialization.py +111 -0
  252. vellum_ee/workflows/display/tests/workflow_serialization/test_no_triggers_no_entrypoint_validation.py +64 -0
  253. vellum_ee/workflows/display/tests/workflow_serialization/test_partial_workflow_meta_display_override.py +55 -0
  254. vellum_ee/workflows/display/tests/workflow_serialization/test_sandbox_dataset_mocks_serialization.py +268 -0
  255. vellum_ee/workflows/display/tests/workflow_serialization/test_sandbox_invalid_pdf_data_url.py +49 -0
  256. vellum_ee/workflows/display/tests/workflow_serialization/test_sandbox_validation_errors.py +112 -0
  257. vellum_ee/workflows/display/tests/workflow_serialization/test_scheduled_trigger_serialization.py +25 -16
  258. vellum_ee/workflows/display/tests/workflow_serialization/test_terminal_node_in_unused_graphs_serialization.py +53 -0
  259. vellum_ee/workflows/display/utils/exceptions.py +34 -0
  260. vellum_ee/workflows/display/utils/expressions.py +463 -52
  261. vellum_ee/workflows/display/utils/metadata.py +98 -33
  262. vellum_ee/workflows/display/utils/tests/test_metadata.py +31 -0
  263. vellum_ee/workflows/display/utils/triggers.py +153 -0
  264. vellum_ee/workflows/display/utils/vellum.py +59 -5
  265. vellum_ee/workflows/display/workflows/base_workflow_display.py +656 -254
  266. vellum_ee/workflows/display/workflows/get_vellum_workflow_display_class.py +26 -0
  267. vellum_ee/workflows/display/workflows/tests/test_workflow_display.py +77 -29
  268. vellum_ee/workflows/server/namespaces.py +18 -0
  269. vellum_ee/workflows/tests/test_display_meta.py +2 -0
  270. vellum_ee/workflows/tests/test_serialize_module.py +174 -7
  271. vellum_ee/workflows/tests/test_server.py +0 -3
  272. vellum_ee/workflows/display/nodes/vellum/function_node.py +0 -14
  273. {vellum_ai-1.11.2.dist-info → vellum_ai-1.13.5.dist-info}/LICENSE +0 -0
  274. {vellum_ai-1.11.2.dist-info → vellum_ai-1.13.5.dist-info}/WHEEL +0 -0
  275. {vellum_ai-1.11.2.dist-info → vellum_ai-1.13.5.dist-info}/entry_points.txt +0 -0
@@ -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.severity_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.type_checker_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.workflow_sandbox_execute_node_response import *
@@ -1,6 +1,13 @@
1
+ import base64
2
+ import binascii
3
+ import re
1
4
  from typing import Any, ContextManager, Iterator, Optional
2
5
 
6
+ from pydantic import field_serializer
7
+
3
8
  from vellum.client.core.pydantic_utilities import UniversalBaseModel
9
+ from vellum.utils.files.constants import BASE64_DATA_URL_PATTERN
10
+ from vellum.utils.files.exceptions import InvalidFileSourceError
4
11
  from vellum.utils.files.read import read_vellum_file
5
12
  from vellum.utils.files.stream import stream_vellum_file
6
13
  from vellum.utils.files.upload import upload_vellum_file
@@ -107,3 +114,22 @@ class VellumFileMixin(UniversalBaseModel):
107
114
  str: A signed URL for accessing the uploaded file
108
115
  """
109
116
  return get_signed_url(self, expiry_seconds=expiry_seconds, vellum_client=vellum_client)
117
+
118
+ @field_serializer("src", check_fields=False)
119
+ @classmethod
120
+ def validate_src_on_serialize(cls, src: str) -> str:
121
+ """Validate the src field during serialization.
122
+
123
+ For PDF base64 data URLs, this validates that the base64 content is properly encoded.
124
+ """
125
+ data_url_match = re.match(BASE64_DATA_URL_PATTERN, src)
126
+ if data_url_match:
127
+ mime_type = data_url_match.group(1) or ""
128
+ if mime_type == "application/pdf":
129
+ base64_content = data_url_match.group(3)
130
+ try:
131
+ base64.b64decode(base64_content, validate=True)
132
+ except binascii.Error as e:
133
+ raise InvalidFileSourceError(f"Invalid base64 encoding in PDF data URL: {e}") from e
134
+
135
+ return src
@@ -1,6 +1,9 @@
1
+ import pytest
1
2
  import base64
2
3
  from unittest.mock import Mock, patch
3
4
 
5
+ from pydantic_core import PydanticSerializationError
6
+
4
7
  from vellum.utils.files import VellumFileMixin
5
8
 
6
9
  # Sample content for testing
@@ -203,3 +206,62 @@ def test_vellum_file_mixin_get_signed_url_method_already_uploaded():
203
206
  assert result == signed_url
204
207
  mock_client.uploaded_files.create.assert_not_called()
205
208
  mock_client.uploaded_files.retrieve.assert_called_once_with(file_id, expiry_seconds=604800)
209
+
210
+
211
+ def test_vellum_file_mixin_serialization_valid_base64():
212
+ """Tests that serialization succeeds with valid base64 data URLs."""
213
+
214
+ # GIVEN a test document with valid base64 content
215
+ content = b"Hello, this is a test document!"
216
+ base64_content = base64.b64encode(content).decode("utf-8")
217
+ src = f"data:application/pdf;base64,{base64_content}"
218
+ test_file = TestDocument(src=src)
219
+
220
+ # WHEN serializing the document
221
+ serialized = test_file.model_dump()
222
+
223
+ # THEN the serialization should succeed and preserve the src
224
+ assert serialized["src"] == src
225
+
226
+
227
+ def test_vellum_file_mixin_serialization_invalid_base64():
228
+ """Tests that serialization raises an error for invalid base64 data URLs."""
229
+
230
+ # GIVEN a test document with invalid base64 content
231
+ invalid_base64 = "not-valid-base64!!!"
232
+ src = f"data:application/pdf;base64,{invalid_base64}"
233
+ test_file = TestDocument(src=src)
234
+
235
+ # WHEN serializing the document
236
+ # THEN a PydanticSerializationError should be raised with InvalidFileSourceError as the cause
237
+ with pytest.raises(PydanticSerializationError, match="Invalid base64 encoding in PDF data URL"):
238
+ test_file.model_dump()
239
+
240
+
241
+ def test_vellum_file_mixin_serialization_non_data_url():
242
+ """Tests that serialization succeeds for non-data URL sources."""
243
+
244
+ # GIVEN a test document with a regular URL source
245
+ src = "https://example.com/document.pdf"
246
+ test_file = TestDocument(src=src)
247
+
248
+ # WHEN serializing the document
249
+ serialized = test_file.model_dump()
250
+
251
+ # THEN the serialization should succeed and preserve the src
252
+ assert serialized["src"] == src
253
+
254
+
255
+ def test_vellum_file_mixin_serialization_vellum_uploaded_file():
256
+ """Tests that serialization succeeds for vellum:uploaded-file sources."""
257
+
258
+ # GIVEN a test document with a vellum:uploaded-file source
259
+ file_id = "12345678-1234-1234-1234-123456789abc"
260
+ src = f"vellum:uploaded-file:{file_id}"
261
+ test_file = TestDocument(src=src)
262
+
263
+ # WHEN serializing the document
264
+ serialized = test_file.model_dump()
265
+
266
+ # THEN the serialization should succeed and preserve the src
267
+ assert serialized["src"] == src
@@ -0,0 +1,95 @@
1
+ import pytest
2
+ from unittest.mock import patch
3
+
4
+ from vellum.utils.vellum_client import create_vellum_client, create_vellum_environment
5
+
6
+
7
+ class TestCreateVellumClient:
8
+ """Tests for create_vellum_client and create_vellum_environment."""
9
+
10
+ @pytest.mark.parametrize(
11
+ ["api_url", "predict_api_url", "expected_predict_url"],
12
+ [
13
+ (None, None, "https://predict.vellum.ai"),
14
+ (None, "https://custom-predict.example.com", "https://custom-predict.example.com"),
15
+ ("CUSTOM_API_URL", None, "https://predict.vellum.ai"),
16
+ ("CUSTOM_API_URL", "https://custom-predict.example.com", "https://custom-predict.example.com"),
17
+ ],
18
+ ids=[
19
+ "defaults_to_standard_predict_url",
20
+ "predict_api_url_overrides_default",
21
+ "api_url_env_var_does_not_affect_predict_when_not_set",
22
+ "predict_api_url_takes_precedence_over_api_url",
23
+ ],
24
+ )
25
+ def test_create_vellum_client__predict_url_resolution(self, api_url, predict_api_url, expected_predict_url):
26
+ """Tests that predict_api_url is resolved correctly based on provided parameters."""
27
+
28
+ # GIVEN no environment variables are set
29
+ with patch.dict("os.environ", {}, clear=True):
30
+ # WHEN creating a vellum client with the given parameters
31
+ client = create_vellum_client(
32
+ api_key="test-api-key",
33
+ api_url=api_url,
34
+ predict_api_url=predict_api_url,
35
+ )
36
+
37
+ # THEN the predict URL should be resolved correctly
38
+ assert client._client_wrapper._environment.predict == expected_predict_url
39
+
40
+ @pytest.mark.parametrize(
41
+ ["env_vars", "predict_api_url", "expected_predict_url"],
42
+ [
43
+ ({"VELLUM_PREDICT_API_URL": "https://env-predict.example.com"}, None, "https://env-predict.example.com"),
44
+ (
45
+ {"VELLUM_PREDICT_API_URL": "https://env-predict.example.com"},
46
+ "https://param-predict.example.com",
47
+ "https://param-predict.example.com",
48
+ ),
49
+ ({"VELLUM_API_URL": "https://env-api.example.com"}, None, "https://env-api.example.com"),
50
+ (
51
+ {
52
+ "VELLUM_API_URL": "https://env-api.example.com",
53
+ "VELLUM_PREDICT_API_URL": "https://env-predict.example.com",
54
+ },
55
+ None,
56
+ "https://env-predict.example.com",
57
+ ),
58
+ ],
59
+ ids=[
60
+ "env_var_predict_api_url_is_used",
61
+ "param_predict_api_url_overrides_env_var",
62
+ "env_var_api_url_fallback_for_predict",
63
+ "env_var_predict_api_url_takes_precedence_over_api_url",
64
+ ],
65
+ )
66
+ def test_create_vellum_client__predict_url_env_var_resolution(
67
+ self, env_vars, predict_api_url, expected_predict_url
68
+ ):
69
+ """Tests that predict_api_url respects environment variables with correct precedence."""
70
+
71
+ # GIVEN specific environment variables are set
72
+ with patch.dict("os.environ", env_vars, clear=True):
73
+ # WHEN creating a vellum client with the given parameters
74
+ client = create_vellum_client(
75
+ api_key="test-api-key",
76
+ predict_api_url=predict_api_url,
77
+ )
78
+
79
+ # THEN the predict URL should be resolved correctly
80
+ assert client._client_wrapper._environment.predict == expected_predict_url
81
+
82
+ def test_create_vellum_environment__predict_api_url_does_not_affect_other_urls(self):
83
+ """Tests that predict_api_url only affects the predict endpoint, not default or documents."""
84
+
85
+ # GIVEN no environment variables are set
86
+ with patch.dict("os.environ", {}, clear=True):
87
+ # WHEN creating a vellum environment with a custom predict_api_url
88
+ environment = create_vellum_environment(predict_api_url="https://custom-predict.example.com")
89
+
90
+ # THEN the predict URL should be customized
91
+ assert environment.predict == "https://custom-predict.example.com"
92
+
93
+ # AND the default and documents URLs should remain unchanged
94
+ assert environment.default == "https://api.vellum.ai"
95
+ assert environment.documents == "https://documents.vellum.ai"
vellum/utils/uuid.py CHANGED
@@ -1,8 +1,25 @@
1
1
  import uuid
2
- from typing import Union
2
+ from typing import Any, Literal, Union, overload
3
+ from typing_extensions import TypeGuard
3
4
 
4
5
 
5
- def is_valid_uuid(val: Union[str, uuid.UUID, None]) -> bool:
6
+ @overload
7
+ def is_valid_uuid(val: None) -> Literal[False]: ...
8
+
9
+
10
+ @overload
11
+ def is_valid_uuid(val: str) -> TypeGuard[str]: ...
12
+
13
+
14
+ @overload
15
+ def is_valid_uuid(val: uuid.UUID) -> TypeGuard[uuid.UUID]: ...
16
+
17
+
18
+ @overload
19
+ def is_valid_uuid(val: Any) -> Literal[False]: ...
20
+
21
+
22
+ def is_valid_uuid(val: Any) -> TypeGuard[Union[str, uuid.UUID]]:
6
23
  try:
7
24
  uuid.UUID(str(val))
8
25
  return True
@@ -9,22 +9,29 @@ def create_vellum_client(
9
9
  api_key: Optional[str] = None,
10
10
  api_url: Optional[str] = None,
11
11
  api_version: Optional[ApiVersionEnum] = None,
12
+ predict_api_url: Optional[str] = None,
12
13
  ) -> Vellum:
13
14
  if api_key is None:
14
15
  api_key = os.getenv("VELLUM_API_KEY", default="")
15
16
 
16
17
  return Vellum(
17
18
  api_key=api_key,
18
- environment=create_vellum_environment(api_url),
19
+ environment=create_vellum_environment(api_url, predict_api_url=predict_api_url),
19
20
  api_version=api_version,
20
21
  )
21
22
 
22
23
 
23
- def create_vellum_environment(api_url: Optional[str] = None) -> VellumEnvironment:
24
+ def create_vellum_environment(
25
+ api_url: Optional[str] = None,
26
+ predict_api_url: Optional[str] = None,
27
+ ) -> VellumEnvironment:
28
+ predict = predict_api_url or _resolve_env(
29
+ [api_url, "VELLUM_PREDICT_API_URL", "VELLUM_API_URL"], "https://predict.vellum.ai"
30
+ )
24
31
  return VellumEnvironment(
25
32
  default=_resolve_env([api_url, "VELLUM_DEFAULT_API_URL", "VELLUM_API_URL"], "https://api.vellum.ai"),
26
33
  documents=_resolve_env([api_url, "VELLUM_DOCUMENTS_API_URL", "VELLUM_API_URL"], "https://documents.vellum.ai"),
27
- predict=_resolve_env([api_url, "VELLUM_PREDICT_API_URL", "VELLUM_API_URL"], "https://predict.vellum.ai"),
34
+ predict=predict,
28
35
  )
29
36
 
30
37
 
@@ -26,15 +26,17 @@ from .nodes import (
26
26
  WebSearchNode,
27
27
  )
28
28
  from .nodes.displayable.tool_calling_node import ToolCallingNode
29
+ from .nodes.mocks import MockNodeExecution
29
30
  from .ports import Port
30
31
  from .references.environment_variable import EnvironmentVariableReference
31
32
  from .references.lazy import LazyReference
32
33
  from .runner import WorkflowRunner
33
34
  from .sandbox import WorkflowSandboxRunner
34
35
  from .state.base import BaseState
35
- from .triggers import IntegrationTrigger, ScheduleTrigger
36
+ from .triggers import ChatMessageTrigger, IntegrationTrigger, ScheduleTrigger
36
37
  from .types.core import Json, MergeBehavior
37
38
  from .types.definition import DeploymentDefinition, MCPServer, VellumIntegrationToolDefinition
39
+ from .utils.functions import tool, use_tool_inputs
38
40
  from .workflows import BaseWorkflow
39
41
 
40
42
  __all__ = [
@@ -48,6 +50,7 @@ __all__ = [
48
50
  "BaseSearchNode",
49
51
  "BaseState",
50
52
  "BaseWorkflow",
53
+ "ChatMessageTrigger",
51
54
  "CodeExecutionNode",
52
55
  "ConditionalNode",
53
56
  "DatasetRow",
@@ -64,6 +67,7 @@ __all__ = [
64
67
  "MapNode",
65
68
  "MCPServer",
66
69
  "MergeBehavior",
70
+ "MockNodeExecution",
67
71
  "NodeException",
68
72
  "NoteNode",
69
73
  "Port",
@@ -73,8 +77,10 @@ __all__ = [
73
77
  "SearchNode",
74
78
  "SubworkflowDeploymentNode",
75
79
  "TemplatingNode",
80
+ "tool",
76
81
  "ToolCallingNode",
77
82
  "TryNode",
83
+ "use_tool_inputs",
78
84
  "VellumIntegrationToolDefinition",
79
85
  "WebSearchNode",
80
86
  "WorkflowErrorCode",
@@ -1,5 +1,8 @@
1
1
  from typing import TYPE_CHECKING, Any, Generic, Optional, Tuple, Type, TypeVar, Union, cast, overload
2
2
 
3
+ from pydantic import GetCoreSchemaHandler, ValidationInfo
4
+ from pydantic_core import core_schema
5
+
3
6
  if TYPE_CHECKING:
4
7
  from vellum.workflows.expressions.accessor import AccessorExpression
5
8
  from vellum.workflows.expressions.add import AddExpression
@@ -65,6 +68,15 @@ class BaseDescriptor(Generic[_T]):
65
68
  def types(self) -> Tuple[Type[_T], ...]:
66
69
  return self._types
67
70
 
71
+ @property
72
+ def normalized_type(self) -> Type:
73
+ all_types = self._types
74
+ if len(all_types) == 1:
75
+ return all_types[0]
76
+ else:
77
+ # Union should be considered a type, but mypy doesn't agree
78
+ return Union[all_types] # type: ignore[return-value]
79
+
68
80
  @property
69
81
  def instance(self) -> Optional[_T]:
70
82
  return self._instance
@@ -179,6 +191,17 @@ class BaseDescriptor(Generic[_T]):
179
191
 
180
192
  return LessThanExpression(lhs=self, rhs=other)
181
193
 
194
+ @overload
195
+ def __lt__(self, other: "BaseDescriptor[_O]") -> "LessThanExpression[_T, _O]": ... # type: ignore[misc]
196
+
197
+ @overload
198
+ def __lt__(self, other: _O) -> "LessThanExpression[_T, _O]": ...
199
+
200
+ def __lt__(self, other: "Union[BaseDescriptor[_O], _O]") -> "LessThanExpression[_T, _O]":
201
+ from vellum.workflows.expressions.less_than import LessThanExpression
202
+
203
+ return LessThanExpression(lhs=self, rhs=other)
204
+
182
205
  @overload
183
206
  def greater_than(self, other: "BaseDescriptor[_O]") -> "GreaterThanExpression[_T, _O]": ...
184
207
 
@@ -190,6 +213,17 @@ class BaseDescriptor(Generic[_T]):
190
213
 
191
214
  return GreaterThanExpression(lhs=self, rhs=other)
192
215
 
216
+ @overload
217
+ def __gt__(self, other: "BaseDescriptor[_O]") -> "GreaterThanExpression[_T, _O]": ... # type: ignore[misc]
218
+
219
+ @overload
220
+ def __gt__(self, other: _O) -> "GreaterThanExpression[_T, _O]": ...
221
+
222
+ def __gt__(self, other: "Union[BaseDescriptor[_O], _O]") -> "GreaterThanExpression[_T, _O]":
223
+ from vellum.workflows.expressions.greater_than import GreaterThanExpression
224
+
225
+ return GreaterThanExpression(lhs=self, rhs=other)
226
+
193
227
  @overload
194
228
  def less_than_or_equal_to(self, other: "BaseDescriptor[_O]") -> "LessThanOrEqualToExpression[_T, _O]": ...
195
229
 
@@ -201,6 +235,17 @@ class BaseDescriptor(Generic[_T]):
201
235
 
202
236
  return LessThanOrEqualToExpression(lhs=self, rhs=other)
203
237
 
238
+ @overload
239
+ def __le__(self, other: "BaseDescriptor[_O]") -> "LessThanOrEqualToExpression[_T, _O]": ... # type: ignore[misc]
240
+
241
+ @overload
242
+ def __le__(self, other: _O) -> "LessThanOrEqualToExpression[_T, _O]": ...
243
+
244
+ def __le__(self, other: "Union[BaseDescriptor[_O], _O]") -> "LessThanOrEqualToExpression[_T, _O]":
245
+ from vellum.workflows.expressions.less_than_or_equal_to import LessThanOrEqualToExpression
246
+
247
+ return LessThanOrEqualToExpression(lhs=self, rhs=other)
248
+
204
249
  @overload
205
250
  def greater_than_or_equal_to(self, other: "BaseDescriptor[_O]") -> "GreaterThanOrEqualToExpression[_T, _O]": ...
206
251
 
@@ -214,6 +259,17 @@ class BaseDescriptor(Generic[_T]):
214
259
 
215
260
  return GreaterThanOrEqualToExpression(lhs=self, rhs=other)
216
261
 
262
+ @overload
263
+ def __ge__(self, other: "BaseDescriptor[_O]") -> "GreaterThanOrEqualToExpression[_T, _O]": ... # type: ignore[misc]
264
+
265
+ @overload
266
+ def __ge__(self, other: _O) -> "GreaterThanOrEqualToExpression[_T, _O]": ...
267
+
268
+ def __ge__(self, other: "Union[BaseDescriptor[_O], _O]") -> "GreaterThanOrEqualToExpression[_T, _O]":
269
+ from vellum.workflows.expressions.greater_than_or_equal_to import GreaterThanOrEqualToExpression
270
+
271
+ return GreaterThanOrEqualToExpression(lhs=self, rhs=other)
272
+
217
273
  @overload
218
274
  def contains(self, other: "BaseDescriptor[_O]") -> "ContainsExpression[_T, _O]": ...
219
275
 
@@ -439,3 +495,33 @@ class BaseDescriptor(Generic[_T]):
439
495
  from vellum.workflows.expressions.minus import MinusExpression
440
496
 
441
497
  return MinusExpression(lhs=self, rhs=other)
498
+
499
+ @classmethod
500
+ def __get_pydantic_core_schema__(
501
+ cls, source_type: Type[Any], handler: GetCoreSchemaHandler
502
+ ) -> core_schema.CoreSchema:
503
+ def validate(value: Any, info: ValidationInfo) -> Any:
504
+ if isinstance(value, cls):
505
+ return value
506
+
507
+ if not isinstance(value, dict):
508
+ raise TypeError(f"Value must be an instance of {cls.__name__} or a dict")
509
+
510
+ context = info.context
511
+ if not isinstance(context, dict):
512
+ raise TypeError(f"Unexpected type for context: {type(context)}")
513
+
514
+ validator = context.get("descriptor_validator")
515
+ if validator and callable(validator):
516
+ return validator(value)
517
+
518
+ from vellum.workflows.references.constant import ConstantValueReference
519
+
520
+ return ConstantValueReference(value)
521
+
522
+ return core_schema.union_schema(
523
+ [
524
+ core_schema.is_instance_schema(cls),
525
+ core_schema.with_info_after_validator_function(validate, core_schema.dict_schema()),
526
+ ]
527
+ )
@@ -132,6 +132,11 @@ class DummyNode(BaseNode[FixtureState]):
132
132
  (FixtureState.alpha + FixtureState.beta, 3),
133
133
  (FixtureState.gamma + FixtureState.delta, "helloel"),
134
134
  (FixtureState.theta + FixtureState.theta, ["baz", "baz"]),
135
+ # Test comparison operators
136
+ (FixtureState.alpha < FixtureState.beta, True),
137
+ (FixtureState.alpha > FixtureState.beta, False),
138
+ (FixtureState.alpha <= FixtureState.beta, True),
139
+ (FixtureState.alpha >= FixtureState.beta, False),
135
140
  ],
136
141
  ids=[
137
142
  "or",
@@ -194,6 +199,10 @@ class DummyNode(BaseNode[FixtureState]):
194
199
  "add_integers",
195
200
  "add_strings",
196
201
  "add_lists",
202
+ "lt_operator",
203
+ "gt_operator",
204
+ "le_operator",
205
+ "ge_operator",
197
206
  ],
198
207
  )
199
208
  def test_resolve_value__happy_path(descriptor, expected_value):
File without changes
@@ -0,0 +1,52 @@
1
+ from vellum.workflows.errors.types import WorkflowError, WorkflowErrorCode, workflow_error_to_vellum_error
2
+
3
+
4
+ def test_workflow_error_to_vellum_error__preserves_raw_data():
5
+ """
6
+ Tests that raw_data is preserved when converting WorkflowError to VellumError.
7
+ """
8
+ # GIVEN a WorkflowError with raw_data containing integration details
9
+ raw_data = {
10
+ "integration": {
11
+ "id": "550e8400-e29b-41d4-a716-446655440000",
12
+ "provider": "COMPOSIO",
13
+ "name": "GITHUB",
14
+ }
15
+ }
16
+ workflow_error = WorkflowError(
17
+ message="Integration credentials unavailable",
18
+ code=WorkflowErrorCode.INTEGRATION_CREDENTIALS_UNAVAILABLE,
19
+ raw_data=raw_data,
20
+ )
21
+
22
+ # WHEN we convert to VellumError
23
+ vellum_error = workflow_error_to_vellum_error(workflow_error)
24
+
25
+ # THEN the raw_data should be preserved
26
+ assert vellum_error.raw_data == raw_data
27
+
28
+ # AND the integration details should be accessible
29
+ raw_data_from_error = vellum_error.raw_data
30
+ assert raw_data_from_error is not None
31
+ integration = raw_data_from_error.get("integration")
32
+ assert isinstance(integration, dict)
33
+ assert integration["name"] == "GITHUB"
34
+ assert integration["provider"] == "COMPOSIO"
35
+
36
+
37
+ def test_workflow_error_to_vellum_error__handles_none_raw_data():
38
+ """
39
+ Tests that None raw_data is handled correctly when converting WorkflowError to VellumError.
40
+ """
41
+ # GIVEN a WorkflowError with no raw_data
42
+ workflow_error = WorkflowError(
43
+ message="Some error",
44
+ code=WorkflowErrorCode.INTERNAL_ERROR,
45
+ raw_data=None,
46
+ )
47
+
48
+ # WHEN we convert to VellumError
49
+ vellum_error = workflow_error_to_vellum_error(workflow_error)
50
+
51
+ # THEN the raw_data should be None
52
+ assert vellum_error.raw_data is None
@@ -115,4 +115,5 @@ def workflow_error_to_vellum_error(error: WorkflowError) -> VellumError:
115
115
  return VellumError(
116
116
  message=error.message,
117
117
  code=_WORKFLOW_ERROR_CODE_TO_VELLUM_ERROR_CODE.get(error.code, "INTERNAL_SERVER_ERROR"),
118
+ raw_data=error.raw_data,
118
119
  )
@@ -1,8 +1,11 @@
1
+ import json
1
2
  from typing import TYPE_CHECKING, Any, Dict, Generic, List, Literal, Optional, Set, Type, Union
2
3
 
3
4
  from pydantic import SerializationInfo, field_serializer, model_serializer
4
5
 
5
6
  from vellum.client.core.pydantic_utilities import UniversalBaseModel
7
+ from vellum.client.types import SeverityEnum
8
+ from vellum.utils.json_encoder import VellumJsonEncoder
6
9
  from vellum.workflows.errors import WorkflowError
7
10
  from vellum.workflows.expressions.accessor import AccessorExpression
8
11
  from vellum.workflows.outputs.base import BaseOutput
@@ -136,6 +139,15 @@ class NodeExecutionFulfilledEvent(_BaseNodeEvent, Generic[OutputsType]):
136
139
  and serialized["body"]["invoked_ports"] is None
137
140
  ):
138
141
  del serialized["body"]["invoked_ports"]
142
+
143
+ if (
144
+ self._event_max_size is not None
145
+ and len(json.dumps(serialized, cls=VellumJsonEncoder)) > self._event_max_size
146
+ and "body" in serialized
147
+ and isinstance(serialized["body"], dict)
148
+ ):
149
+ serialized["body"]["outputs"] = {}
150
+
139
151
  return serialized
140
152
 
141
153
 
@@ -171,6 +183,17 @@ class NodeExecutionResumedEvent(_BaseNodeEvent):
171
183
  body: NodeExecutionResumedBody
172
184
 
173
185
 
186
+ class NodeExecutionLogBody(_BaseNodeExecutionBody):
187
+ attributes: Optional[Dict[str, Any]] = None
188
+ severity: SeverityEnum
189
+ message: str
190
+
191
+
192
+ class NodeExecutionLogEvent(_BaseNodeEvent):
193
+ name: Literal["node.execution.log"] = "node.execution.log"
194
+ body: NodeExecutionLogBody
195
+
196
+
174
197
  NodeEvent = Union[
175
198
  NodeExecutionInitiatedEvent,
176
199
  NodeExecutionStreamingEvent,
@@ -178,4 +201,5 @@ NodeEvent = Union[
178
201
  NodeExecutionRejectedEvent,
179
202
  NodeExecutionPausedEvent,
180
203
  NodeExecutionResumedEvent,
204
+ NodeExecutionLogEvent,
181
205
  ]