vellum-ai 0.14.71__py3-none-any.whl → 0.14.73__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 (77) hide show
  1. vellum/__init__.py +8 -0
  2. vellum/client/core/client_wrapper.py +1 -1
  3. vellum/client/core/serialization.py +1 -0
  4. vellum/client/types/__init__.py +8 -0
  5. vellum/client/types/build_status_enum.py +5 -0
  6. vellum/client/types/container_image_build_config.py +20 -0
  7. vellum/client/types/container_image_read.py +4 -0
  8. vellum/client/types/execute_api_response.py +2 -2
  9. vellum/client/types/folder_entity.py +2 -0
  10. vellum/client/types/folder_entity_dataset.py +26 -0
  11. vellum/client/types/folder_entity_dataset_data.py +25 -0
  12. vellum/plugins/vellum_mypy.py +1 -1
  13. vellum/types/build_status_enum.py +3 -0
  14. vellum/types/container_image_build_config.py +3 -0
  15. vellum/types/folder_entity_dataset.py +3 -0
  16. vellum/types/folder_entity_dataset_data.py +3 -0
  17. vellum/workflows/events/__init__.py +2 -0
  18. vellum/workflows/events/stream.py +28 -0
  19. vellum/workflows/events/workflow.py +3 -2
  20. vellum/workflows/nodes/core/retry_node/tests/test_node.py +1 -1
  21. vellum/workflows/nodes/displayable/api_node/node.py +2 -0
  22. vellum/workflows/nodes/displayable/api_node/tests/test_api_node.py +43 -0
  23. vellum/workflows/nodes/displayable/bases/api_node/node.py +6 -0
  24. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +30 -4
  25. vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py +43 -3
  26. vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +68 -58
  27. vellum/workflows/nodes/experimental/tool_calling_node/node.py +11 -11
  28. vellum/workflows/nodes/experimental/tool_calling_node/tests/__init__.py +0 -0
  29. vellum/workflows/nodes/experimental/tool_calling_node/tests/test_utils.py +49 -0
  30. vellum/workflows/nodes/experimental/tool_calling_node/utils.py +69 -8
  31. vellum/workflows/ports/utils.py +26 -6
  32. vellum/workflows/runner/runner.py +56 -6
  33. vellum/workflows/types/core.py +12 -0
  34. vellum/workflows/types/definition.py +6 -0
  35. vellum/workflows/utils/functions.py +64 -10
  36. vellum/workflows/utils/pydantic_schema.py +38 -0
  37. vellum/workflows/utils/tests/test_functions.py +161 -11
  38. vellum/workflows/utils/tests/test_vellum_variables.py +25 -1
  39. vellum/workflows/utils/vellum_variables.py +30 -0
  40. vellum/workflows/workflows/base.py +11 -5
  41. {vellum_ai-0.14.71.dist-info → vellum_ai-0.14.73.dist-info}/METADATA +1 -1
  42. {vellum_ai-0.14.71.dist-info → vellum_ai-0.14.73.dist-info}/RECORD +77 -64
  43. vellum_cli/image_push.py +1 -5
  44. vellum_cli/push.py +12 -7
  45. vellum_cli/tests/test_image_push.py +1 -2
  46. vellum_cli/tests/test_push.py +33 -2
  47. vellum_ee/workflows/display/nodes/utils.py +2 -2
  48. vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py +8 -1
  49. vellum_ee/workflows/display/tests/test_base_workflow_display.py +1 -1
  50. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_adornments_serialization.py +1 -1
  51. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/test_attributes_serialization.py +1 -1
  52. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +5 -5
  53. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +12 -12
  54. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +10 -10
  55. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_default_state_serialization.py +3 -3
  56. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_error_node_serialization.py +3 -3
  57. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_generic_node_serialization.py +20 -9
  58. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_guardrail_node_serialization.py +3 -3
  59. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_prompt_node_serialization.py +3 -3
  60. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +8 -8
  61. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +6 -6
  62. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +3 -3
  63. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_prompt_deployment_serialization.py +8 -8
  64. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_search_node_serialization.py +3 -3
  65. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_deployment_serialization.py +4 -4
  66. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py +3 -3
  67. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py +2 -2
  68. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py +5 -5
  69. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py +1 -1
  70. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py +1 -1
  71. vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py +2 -2
  72. vellum_ee/workflows/display/utils/auto_layout.py +1 -1
  73. vellum_ee/workflows/display/workflows/base_workflow_display.py +179 -4
  74. vellum_ee/workflows/tests/test_serialize_module.py +47 -0
  75. {vellum_ai-0.14.71.dist-info → vellum_ai-0.14.73.dist-info}/LICENSE +0 -0
  76. {vellum_ai-0.14.71.dist-info → vellum_ai-0.14.73.dist-info}/WHEEL +0 -0
  77. {vellum_ai-0.14.71.dist-info → vellum_ai-0.14.73.dist-info}/entry_points.txt +0 -0
@@ -1,12 +1,14 @@
1
1
  import dataclasses
2
2
  import inspect
3
- from typing import TYPE_CHECKING, Any, Callable, Optional, Type, Union, get_args, get_origin
3
+ from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Type, Union, get_args, get_origin
4
4
 
5
5
  from pydantic import BaseModel
6
6
  from pydantic_core import PydanticUndefined
7
7
  from pydash import snake_case
8
8
 
9
+ from vellum import Vellum
9
10
  from vellum.client.types.function_definition import FunctionDefinition
11
+ from vellum.workflows.utils.vellum_variables import vellum_variable_type_to_openapi_type
10
12
 
11
13
  if TYPE_CHECKING:
12
14
  from vellum.workflows.workflows.base import BaseWorkflow
@@ -24,27 +26,27 @@ type_map = {
24
26
  }
25
27
 
26
28
 
27
- def _compile_annotation(annotation: Optional[Any], defs: dict[str, Any]) -> dict:
29
+ def compile_annotation(annotation: Optional[Any], defs: dict[str, Any]) -> dict:
28
30
  if annotation is None:
29
31
  return {"type": "null"}
30
32
 
31
33
  if get_origin(annotation) is Union:
32
- return {"anyOf": [_compile_annotation(a, defs) for a in get_args(annotation)]}
34
+ return {"anyOf": [compile_annotation(a, defs) for a in get_args(annotation)]}
33
35
 
34
36
  if get_origin(annotation) is dict:
35
37
  _, value_type = get_args(annotation)
36
- return {"type": "object", "additionalProperties": _compile_annotation(value_type, defs)}
38
+ return {"type": "object", "additionalProperties": compile_annotation(value_type, defs)}
37
39
 
38
40
  if get_origin(annotation) is list:
39
41
  item_type = get_args(annotation)[0]
40
- return {"type": "array", "items": _compile_annotation(item_type, defs)}
42
+ return {"type": "array", "items": compile_annotation(item_type, defs)}
41
43
 
42
44
  if dataclasses.is_dataclass(annotation):
43
45
  if annotation.__name__ not in defs:
44
46
  properties = {}
45
47
  required = []
46
48
  for field in dataclasses.fields(annotation):
47
- properties[field.name] = _compile_annotation(field.type, defs)
49
+ properties[field.name] = compile_annotation(field.type, defs)
48
50
  if field.default is dataclasses.MISSING:
49
51
  required.append(field.name)
50
52
  else:
@@ -59,7 +61,7 @@ def _compile_annotation(annotation: Optional[Any], defs: dict[str, Any]) -> dict
59
61
  for field_name, field in annotation.model_fields.items():
60
62
  # Mypy is incorrect here, the `annotation` attribute is defined on `FieldInfo`
61
63
  field_annotation = field.annotation # type: ignore[attr-defined]
62
- properties[field_name] = _compile_annotation(field_annotation, defs)
64
+ properties[field_name] = compile_annotation(field_annotation, defs)
63
65
  if field.default is PydanticUndefined:
64
66
  required.append(field_name)
65
67
  else:
@@ -86,6 +88,19 @@ def _compile_default_value(default: Any) -> Any:
86
88
  return default
87
89
 
88
90
 
91
+ def _compile_deployment_workflow_input(input_var: Any) -> dict[str, Any]:
92
+ """
93
+ Converts a deployment workflow input variable to a JSON schema type definition.
94
+ """
95
+ primitive_type = vellum_variable_type_to_openapi_type(input_var.type)
96
+ input_schema = {"type": primitive_type}
97
+
98
+ if input_var.default is not None:
99
+ input_schema["default"] = input_var.default.value
100
+
101
+ return input_schema
102
+
103
+
89
104
  def compile_function_definition(function: Callable) -> FunctionDefinition:
90
105
  """
91
106
  Converts a Python function into our Vellum-native FunctionDefinition type.
@@ -100,7 +115,7 @@ def compile_function_definition(function: Callable) -> FunctionDefinition:
100
115
  required = []
101
116
  defs: dict[str, Any] = {}
102
117
  for param in signature.parameters.values():
103
- properties[param.name] = _compile_annotation(param.annotation, defs)
118
+ properties[param.name] = compile_annotation(param.annotation, defs)
104
119
  if param.default is inspect.Parameter.empty:
105
120
  required.append(param.name)
106
121
  else:
@@ -117,7 +132,7 @@ def compile_function_definition(function: Callable) -> FunctionDefinition:
117
132
  )
118
133
 
119
134
 
120
- def compile_workflow_function_definition(workflow_class: Type["BaseWorkflow"]) -> FunctionDefinition:
135
+ def compile_inline_workflow_function_definition(workflow_class: Type["BaseWorkflow"]) -> FunctionDefinition:
121
136
  """
122
137
  Converts a base workflow class into our Vellum-native FunctionDefinition type.
123
138
  """
@@ -133,7 +148,7 @@ def compile_workflow_function_definition(workflow_class: Type["BaseWorkflow"]) -
133
148
  if name.startswith("__"):
134
149
  continue
135
150
 
136
- properties[name] = _compile_annotation(field_type, defs)
151
+ properties[name] = compile_annotation(field_type, defs)
137
152
 
138
153
  # Check if the field has a default value
139
154
  if name not in vars_inputs_class:
@@ -151,3 +166,42 @@ def compile_workflow_function_definition(workflow_class: Type["BaseWorkflow"]) -
151
166
  description=workflow_class.__doc__,
152
167
  parameters=parameters,
153
168
  )
169
+
170
+
171
+ def compile_deployment_workflow_function_definition(
172
+ deployment_config: Dict[str, str],
173
+ vellum_client: Vellum,
174
+ ) -> FunctionDefinition:
175
+ """
176
+ Converts a deployment workflow config into our Vellum-native FunctionDefinition type.
177
+
178
+ Args:
179
+ deployment_config: Dict with 'deployment' and 'release_tag' keys
180
+ vellum_client: Vellum client instance
181
+ """
182
+ deployment = deployment_config["deployment"]
183
+ release_tag = deployment_config["release_tag"]
184
+
185
+ workflow_deployment_release = vellum_client.release_reviews.retrieve_workflow_deployment_release(
186
+ deployment, release_tag
187
+ )
188
+
189
+ input_variables = workflow_deployment_release.workflow_version.input_variables
190
+ description = workflow_deployment_release.description
191
+
192
+ properties = {}
193
+ required = []
194
+
195
+ for input_var in input_variables:
196
+ properties[input_var.key] = _compile_deployment_workflow_input(input_var)
197
+
198
+ if input_var.required and input_var.default is None:
199
+ required.append(input_var.key)
200
+
201
+ parameters = {"type": "object", "properties": properties, "required": required}
202
+
203
+ return FunctionDefinition(
204
+ name=deployment,
205
+ description=description,
206
+ parameters=parameters,
207
+ )
@@ -0,0 +1,38 @@
1
+ import inspect
2
+ from typing import Any, Dict
3
+
4
+ from pydantic import BaseModel
5
+
6
+ from vellum.workflows.utils.functions import compile_annotation
7
+
8
+
9
+ def normalize_json(schema_input: Any) -> Any:
10
+ """
11
+ Recursively normalize JSON data by converting Pydantic models to JSON schema.
12
+
13
+ This function processes dictionaries recursively to find and convert any
14
+ Pydantic model classes or instances to their JSON schema representation.
15
+
16
+ Args:
17
+ schema_input: Can be a Pydantic model class, instance, dict, or any other value
18
+
19
+ Returns:
20
+ Normalized JSON data with Pydantic models converted to JSON schema
21
+ """
22
+ if isinstance(schema_input, dict):
23
+ return {key: normalize_json(value) for key, value in schema_input.items()}
24
+
25
+ if inspect.isclass(schema_input) and issubclass(schema_input, BaseModel):
26
+ defs: Dict[str, Any] = {}
27
+ result = compile_annotation(schema_input, defs)
28
+
29
+ if "$ref" in result and defs:
30
+ ref_name = result["$ref"].split("/")[-1]
31
+ if ref_name in defs:
32
+ return defs[ref_name]
33
+
34
+ return result
35
+ elif isinstance(schema_input, BaseModel):
36
+ return {key: normalize_json(getattr(schema_input, key)) for key in schema_input.__class__.model_fields.keys()}
37
+ else:
38
+ return schema_input
@@ -1,14 +1,21 @@
1
1
  from dataclasses import dataclass
2
+ from unittest.mock import Mock
2
3
  from typing import Dict, List, Optional, Union
3
4
 
4
5
  from pydantic import BaseModel
5
6
 
6
7
  from vellum.client.types.function_definition import FunctionDefinition
8
+ from vellum.client.types.string_vellum_value import StringVellumValue
9
+ from vellum.client.types.vellum_variable import VellumVariable
7
10
  from vellum.workflows import BaseWorkflow
8
11
  from vellum.workflows.inputs.base import BaseInputs
9
12
  from vellum.workflows.nodes.bases.base import BaseNode
10
13
  from vellum.workflows.state.base import BaseState
11
- from vellum.workflows.utils.functions import compile_function_definition, compile_workflow_function_definition
14
+ from vellum.workflows.utils.functions import (
15
+ compile_deployment_workflow_function_definition,
16
+ compile_function_definition,
17
+ compile_inline_workflow_function_definition,
18
+ )
12
19
 
13
20
 
14
21
  def test_compile_function_definition__just_name():
@@ -299,7 +306,7 @@ def test_compile_function_definition__lambda():
299
306
  )
300
307
 
301
308
 
302
- def test_compile_workflow_function_definition():
309
+ def test_compile_inline_workflow_function_definition():
303
310
  class MyNode(BaseNode):
304
311
  pass
305
312
 
@@ -307,7 +314,7 @@ def test_compile_workflow_function_definition():
307
314
  graph = MyNode
308
315
 
309
316
  # WHEN compiling the function
310
- compiled_function = compile_workflow_function_definition(MyWorkflow)
317
+ compiled_function = compile_inline_workflow_function_definition(MyWorkflow)
311
318
 
312
319
  # THEN it should return the compiled function definition
313
320
  assert compiled_function == FunctionDefinition(
@@ -316,7 +323,7 @@ def test_compile_workflow_function_definition():
316
323
  )
317
324
 
318
325
 
319
- def test_compile_workflow_function_definition__docstring():
326
+ def test_compile_inline_workflow_function_definition__docstring():
320
327
  class MyNode(BaseNode):
321
328
  pass
322
329
 
@@ -328,7 +335,7 @@ def test_compile_workflow_function_definition__docstring():
328
335
  graph = MyNode
329
336
 
330
337
  # WHEN compiling the function
331
- compiled_function = compile_workflow_function_definition(MyWorkflow)
338
+ compiled_function = compile_inline_workflow_function_definition(MyWorkflow)
332
339
 
333
340
  # THEN it should return the compiled function definition
334
341
  assert compiled_function == FunctionDefinition(
@@ -338,7 +345,7 @@ def test_compile_workflow_function_definition__docstring():
338
345
  )
339
346
 
340
347
 
341
- def test_compile_workflow_function_definition__all_args():
348
+ def test_compile_inline_workflow_function_definition__all_args():
342
349
  class MyInputs(BaseInputs):
343
350
  a: str
344
351
  b: int
@@ -354,7 +361,7 @@ def test_compile_workflow_function_definition__all_args():
354
361
  graph = MyNode
355
362
 
356
363
  # WHEN compiling the workflow
357
- compiled_function = compile_workflow_function_definition(MyWorkflow)
364
+ compiled_function = compile_inline_workflow_function_definition(MyWorkflow)
358
365
 
359
366
  # THEN it should return the compiled function definition
360
367
  assert compiled_function == FunctionDefinition(
@@ -374,7 +381,7 @@ def test_compile_workflow_function_definition__all_args():
374
381
  )
375
382
 
376
383
 
377
- def test_compile_workflow_function_definition__unions():
384
+ def test_compile_inline_workflow_function_definition__unions():
378
385
  # GIVEN a workflow with a union
379
386
  class MyInputs(BaseInputs):
380
387
  a: Union[str, int]
@@ -386,7 +393,7 @@ def test_compile_workflow_function_definition__unions():
386
393
  graph = MyNode
387
394
 
388
395
  # WHEN compiling the workflow
389
- compiled_function = compile_workflow_function_definition(MyWorkflow)
396
+ compiled_function = compile_inline_workflow_function_definition(MyWorkflow)
390
397
 
391
398
  # THEN it should return the compiled function definition
392
399
  assert compiled_function == FunctionDefinition(
@@ -399,7 +406,7 @@ def test_compile_workflow_function_definition__unions():
399
406
  )
400
407
 
401
408
 
402
- def test_compile_workflow_function_definition__optionals():
409
+ def test_compile_inline_workflow_function_definition__optionals():
403
410
  class MyInputs(BaseInputs):
404
411
  a: str
405
412
  b: Optional[str]
@@ -414,7 +421,7 @@ def test_compile_workflow_function_definition__optionals():
414
421
  graph = MyNode
415
422
 
416
423
  # WHEN compiling the workflow
417
- compiled_function = compile_workflow_function_definition(MyWorkflow)
424
+ compiled_function = compile_inline_workflow_function_definition(MyWorkflow)
418
425
 
419
426
  # THEN it should return the compiled function definition
420
427
  assert compiled_function == FunctionDefinition(
@@ -431,3 +438,146 @@ def test_compile_workflow_function_definition__optionals():
431
438
  "required": ["a", "b", "c"],
432
439
  },
433
440
  )
441
+
442
+
443
+ def test_compile_deployment_workflow_function_definition__just_name():
444
+ # GIVEN a mock Vellum client and deployment
445
+ mock_client = Mock()
446
+ mock_release = Mock()
447
+ mock_release.workflow_version.input_variables = []
448
+ mock_release.description = "This is a test deployment"
449
+ mock_client.release_reviews.retrieve_workflow_deployment_release.return_value = mock_release
450
+
451
+ deployment_config = {"deployment": "my_deployment", "release_tag": "latest"}
452
+
453
+ # WHEN compiling the deployment workflow function
454
+ compiled_function = compile_deployment_workflow_function_definition(deployment_config, mock_client)
455
+
456
+ # THEN it should return the compiled function definition (same structure as function test)
457
+ assert compiled_function == FunctionDefinition(
458
+ name="my_deployment",
459
+ description="This is a test deployment",
460
+ parameters={"type": "object", "properties": {}, "required": []},
461
+ )
462
+
463
+
464
+ def test_compile_deployment_workflow_function_definition__all_args():
465
+ # GIVEN a mock Vellum client and deployment
466
+ mock_client = Mock()
467
+ mock_release = Mock()
468
+
469
+ mock_inputs = []
470
+ for key, vellum_type in [
471
+ ("a", "STRING"),
472
+ ("b", "NUMBER"),
473
+ ("c", "JSON"),
474
+ ("d", "CHAT_HISTORY"),
475
+ ("e", "SEARCH_RESULTS"),
476
+ ("f", "ERROR"),
477
+ ("g", "ARRAY"),
478
+ ("h", "FUNCTION_CALL"),
479
+ ("i", "IMAGE"),
480
+ ("j", "AUDIO"),
481
+ ("k", "DOCUMENT"),
482
+ ("l", "NULL"),
483
+ ]:
484
+ mock_input = VellumVariable(
485
+ id=f"input_{key}",
486
+ key=key,
487
+ type=vellum_type,
488
+ required=True,
489
+ default=None,
490
+ )
491
+ mock_inputs.append(mock_input)
492
+
493
+ mock_release.workflow_version.input_variables = mock_inputs
494
+ mock_release.description = "This is a test deployment"
495
+ mock_client.release_reviews.retrieve_workflow_deployment_release.return_value = mock_release
496
+
497
+ deployment_config = {"deployment": "my_deployment", "release_tag": "latest"}
498
+
499
+ # WHEN compiling the deployment workflow function
500
+ compiled_function = compile_deployment_workflow_function_definition(deployment_config, mock_client)
501
+
502
+ # THEN it should return the compiled function definition
503
+ assert compiled_function == FunctionDefinition(
504
+ name="my_deployment",
505
+ description="This is a test deployment",
506
+ parameters={
507
+ "type": "object",
508
+ "properties": {
509
+ "a": {"type": "string"},
510
+ "b": {"type": "number"},
511
+ "c": {"type": "object"},
512
+ "d": {"type": "array"},
513
+ "e": {"type": "array"},
514
+ "f": {"type": "object"},
515
+ "g": {"type": "array"},
516
+ "h": {"type": "object"},
517
+ "i": {"type": "object"},
518
+ "j": {"type": "object"},
519
+ "k": {"type": "object"},
520
+ "l": {"type": "null"},
521
+ },
522
+ "required": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l"],
523
+ },
524
+ )
525
+
526
+
527
+ def test_compile_deployment_workflow_function_definition__defaults():
528
+ # GIVEN a mock Vellum client and deployment
529
+ mock_client = Mock()
530
+ mock_release = Mock()
531
+
532
+ mock_inputs = []
533
+
534
+ mock_input_no_default = VellumVariable(
535
+ id="no_default",
536
+ key="no_default",
537
+ type="STRING",
538
+ required=True,
539
+ default=None,
540
+ )
541
+ mock_inputs.append(mock_input_no_default)
542
+
543
+ mock_input_null_default = VellumVariable(
544
+ id="null_default",
545
+ key="null_default",
546
+ type="STRING",
547
+ required=False,
548
+ default=StringVellumValue(value=None),
549
+ )
550
+ mock_inputs.append(mock_input_null_default)
551
+
552
+ mock_input_actual_default = VellumVariable(
553
+ id="actual_default",
554
+ key="actual_default",
555
+ type="STRING",
556
+ required=False,
557
+ default=StringVellumValue(value="hello world"),
558
+ )
559
+ mock_inputs.append(mock_input_actual_default)
560
+
561
+ mock_release.workflow_version.input_variables = mock_inputs
562
+ mock_release.description = "This is a test deployment"
563
+ mock_client.release_reviews.retrieve_workflow_deployment_release.return_value = mock_release
564
+
565
+ deployment_config = {"deployment": "my_deployment", "release_tag": "latest"}
566
+
567
+ # WHEN compiling the deployment workflow function
568
+ compiled_function = compile_deployment_workflow_function_definition(deployment_config, mock_client)
569
+
570
+ # THEN it should return the compiled function definition with proper default handling
571
+ assert compiled_function == FunctionDefinition(
572
+ name="my_deployment",
573
+ description="This is a test deployment",
574
+ parameters={
575
+ "type": "object",
576
+ "properties": {
577
+ "no_default": {"type": "string"},
578
+ "null_default": {"type": "string", "default": None},
579
+ "actual_default": {"type": "string", "default": "hello world"},
580
+ },
581
+ "required": ["no_default"],
582
+ },
583
+ )
@@ -3,7 +3,10 @@ from typing import List, Optional
3
3
 
4
4
  from vellum import ChatMessage, SearchResult, VellumAudio, VellumDocument, VellumImage
5
5
  from vellum.workflows.types.core import Json
6
- from vellum.workflows.utils.vellum_variables import primitive_type_to_vellum_variable_type
6
+ from vellum.workflows.utils.vellum_variables import (
7
+ primitive_type_to_vellum_variable_type,
8
+ vellum_variable_type_to_openapi_type,
9
+ )
7
10
 
8
11
 
9
12
  @pytest.mark.parametrize(
@@ -31,3 +34,24 @@ from vellum.workflows.utils.vellum_variables import primitive_type_to_vellum_var
31
34
  )
32
35
  def test_primitive_type_to_vellum_variable_type(type_, expected):
33
36
  assert primitive_type_to_vellum_variable_type(type_) == expected
37
+
38
+
39
+ @pytest.mark.parametrize(
40
+ "vellum_type, expected",
41
+ [
42
+ ("STRING", "string"),
43
+ ("NUMBER", "number"),
44
+ ("JSON", "object"),
45
+ ("CHAT_HISTORY", "array"),
46
+ ("SEARCH_RESULTS", "array"),
47
+ ("ERROR", "object"),
48
+ ("ARRAY", "array"),
49
+ ("FUNCTION_CALL", "object"),
50
+ ("IMAGE", "object"),
51
+ ("AUDIO", "object"),
52
+ ("DOCUMENT", "object"),
53
+ ("NULL", "null"),
54
+ ],
55
+ )
56
+ def test_vellum_variable_type_to_openapi_type(vellum_type, expected):
57
+ assert vellum_variable_type_to_openapi_type(vellum_type) == expected
@@ -78,6 +78,36 @@ def primitive_type_to_vellum_variable_type(type_: Union[Type, BaseDescriptor]) -
78
78
  return "JSON"
79
79
 
80
80
 
81
+ def vellum_variable_type_to_openapi_type(vellum_type: VellumVariableType) -> str:
82
+ """Converts a VellumVariableType to a JSON schema primitive type string"""
83
+ if vellum_type == "STRING":
84
+ return "string"
85
+ elif vellum_type == "NUMBER":
86
+ return "number"
87
+ elif vellum_type == "JSON":
88
+ return "object"
89
+ elif vellum_type == "CHAT_HISTORY":
90
+ return "array"
91
+ elif vellum_type == "SEARCH_RESULTS":
92
+ return "array"
93
+ elif vellum_type == "ERROR":
94
+ return "object"
95
+ elif vellum_type == "ARRAY":
96
+ return "array"
97
+ elif vellum_type == "FUNCTION_CALL":
98
+ return "object"
99
+ elif vellum_type == "IMAGE":
100
+ return "object"
101
+ elif vellum_type == "AUDIO":
102
+ return "object"
103
+ elif vellum_type == "DOCUMENT":
104
+ return "object"
105
+ elif vellum_type == "NULL":
106
+ return "null"
107
+ else:
108
+ return "object"
109
+
110
+
81
111
  def _is_type_optionally_equal(type_: Type, target_type: Type) -> bool:
82
112
  if type_ == target_type:
83
113
  return True
@@ -42,6 +42,7 @@ from vellum.workflows.events.node import (
42
42
  NodeExecutionStreamingBody,
43
43
  NodeExecutionStreamingEvent,
44
44
  )
45
+ from vellum.workflows.events.stream import WorkflowEventGenerator
45
46
  from vellum.workflows.events.workflow import (
46
47
  GenericWorkflowEvent,
47
48
  WorkflowExecutionFulfilledBody,
@@ -167,7 +168,7 @@ class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
167
168
  WorkflowExecutionPausedEvent,
168
169
  ]
169
170
 
170
- WorkflowEventStream = Generator[WorkflowEvent, None, None]
171
+ WorkflowEventStream = WorkflowEventGenerator[WorkflowEvent]
171
172
 
172
173
  def __init__(
173
174
  self,
@@ -444,7 +445,7 @@ class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
444
445
  """
445
446
 
446
447
  should_yield = event_filter or workflow_event_filter
447
- for event in WorkflowRunner(
448
+ runner_stream = WorkflowRunner(
448
449
  self,
449
450
  inputs=inputs,
450
451
  state=state,
@@ -454,9 +455,14 @@ class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
454
455
  node_output_mocks=node_output_mocks,
455
456
  max_concurrency=max_concurrency,
456
457
  init_execution_context=self._execution_context,
457
- ).stream():
458
- if should_yield(self.__class__, event):
459
- yield event
458
+ ).stream()
459
+
460
+ def _generate_filtered_events() -> Generator[BaseWorkflow.WorkflowEvent, None, None]:
461
+ for event in runner_stream:
462
+ if should_yield(self.__class__, event):
463
+ yield event
464
+
465
+ return WorkflowEventGenerator(_generate_filtered_events(), runner_stream.span_id)
460
466
 
461
467
  def validate(self) -> None:
462
468
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.14.71
3
+ Version: 0.14.73
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0