vellum-ai 1.2.3__py3-none-any.whl → 1.2.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.
Files changed (96) hide show
  1. vellum/__init__.py +48 -0
  2. vellum/client/core/client_wrapper.py +2 -2
  3. vellum/client/resources/workflows/client.py +20 -0
  4. vellum/client/resources/workflows/raw_client.py +20 -0
  5. vellum/client/types/__init__.py +48 -0
  6. vellum/client/types/audio_input.py +30 -0
  7. vellum/client/types/code_executor_input.py +8 -0
  8. vellum/client/types/document_input.py +30 -0
  9. vellum/client/types/image_input.py +30 -0
  10. vellum/client/types/named_scenario_input_audio_variable_value_request.py +22 -0
  11. vellum/client/types/named_scenario_input_document_variable_value_request.py +22 -0
  12. vellum/client/types/named_scenario_input_image_variable_value_request.py +22 -0
  13. vellum/client/types/named_scenario_input_request.py +8 -0
  14. vellum/client/types/named_scenario_input_video_variable_value_request.py +22 -0
  15. vellum/client/types/named_test_case_audio_variable_value.py +26 -0
  16. vellum/client/types/named_test_case_audio_variable_value_request.py +26 -0
  17. vellum/client/types/named_test_case_document_variable_value.py +22 -0
  18. vellum/client/types/named_test_case_document_variable_value_request.py +22 -0
  19. vellum/client/types/named_test_case_image_variable_value.py +22 -0
  20. vellum/client/types/named_test_case_image_variable_value_request.py +22 -0
  21. vellum/client/types/named_test_case_variable_value.py +8 -0
  22. vellum/client/types/named_test_case_variable_value_request.py +8 -0
  23. vellum/client/types/named_test_case_video_variable_value.py +22 -0
  24. vellum/client/types/named_test_case_video_variable_value_request.py +22 -0
  25. vellum/client/types/node_execution_span_attributes.py +1 -0
  26. vellum/client/types/scenario_input.py +11 -1
  27. vellum/client/types/scenario_input_audio_variable_value.py +22 -0
  28. vellum/client/types/scenario_input_document_variable_value.py +22 -0
  29. vellum/client/types/scenario_input_image_variable_value.py +22 -0
  30. vellum/client/types/scenario_input_video_variable_value.py +22 -0
  31. vellum/client/types/span_link.py +1 -1
  32. vellum/client/types/span_link_type_enum.py +1 -1
  33. vellum/client/types/test_case_audio_variable_value.py +27 -0
  34. vellum/client/types/test_case_document_variable_value.py +27 -0
  35. vellum/client/types/test_case_image_variable_value.py +27 -0
  36. vellum/client/types/test_case_variable_value.py +8 -0
  37. vellum/client/types/test_case_video_variable_value.py +27 -0
  38. vellum/client/types/video_input.py +30 -0
  39. vellum/client/types/workflow_push_deployment_config_request.py +1 -0
  40. vellum/types/audio_input.py +3 -0
  41. vellum/types/document_input.py +3 -0
  42. vellum/types/image_input.py +3 -0
  43. vellum/types/named_scenario_input_audio_variable_value_request.py +3 -0
  44. vellum/types/named_scenario_input_document_variable_value_request.py +3 -0
  45. vellum/types/named_scenario_input_image_variable_value_request.py +3 -0
  46. vellum/types/named_scenario_input_video_variable_value_request.py +3 -0
  47. vellum/types/named_test_case_audio_variable_value.py +3 -0
  48. vellum/types/named_test_case_audio_variable_value_request.py +3 -0
  49. vellum/types/named_test_case_document_variable_value.py +3 -0
  50. vellum/types/named_test_case_document_variable_value_request.py +3 -0
  51. vellum/types/named_test_case_image_variable_value.py +3 -0
  52. vellum/types/named_test_case_image_variable_value_request.py +3 -0
  53. vellum/types/named_test_case_video_variable_value.py +3 -0
  54. vellum/types/named_test_case_video_variable_value_request.py +3 -0
  55. vellum/types/scenario_input_audio_variable_value.py +3 -0
  56. vellum/types/scenario_input_document_variable_value.py +3 -0
  57. vellum/types/scenario_input_image_variable_value.py +3 -0
  58. vellum/types/scenario_input_video_variable_value.py +3 -0
  59. vellum/types/test_case_audio_variable_value.py +3 -0
  60. vellum/types/test_case_document_variable_value.py +3 -0
  61. vellum/types/test_case_image_variable_value.py +3 -0
  62. vellum/types/test_case_video_variable_value.py +3 -0
  63. vellum/types/video_input.py +3 -0
  64. vellum/workflows/events/tests/test_event.py +9 -0
  65. vellum/workflows/events/types.py +3 -1
  66. vellum/workflows/integrations/tests/test_mcp_service.py +40 -1
  67. vellum/workflows/nodes/core/templating_node/node.py +3 -2
  68. vellum/workflows/nodes/core/templating_node/tests/test_templating_node.py +129 -0
  69. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +12 -0
  70. vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py +41 -0
  71. vellum/workflows/nodes/displayable/bases/utils.py +38 -1
  72. vellum/workflows/nodes/displayable/code_execution_node/utils.py +3 -20
  73. vellum/workflows/nodes/displayable/inline_prompt_node/node.py +3 -26
  74. vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +3 -25
  75. vellum/workflows/nodes/utils.py +26 -1
  76. vellum/workflows/resolvers/base.py +18 -1
  77. vellum/workflows/resolvers/resolver.py +42 -0
  78. vellum/workflows/resolvers/tests/test_resolver.py +59 -0
  79. vellum/workflows/types/definition.py +1 -0
  80. vellum/workflows/utils/functions.py +4 -0
  81. vellum/workflows/utils/tests/test_functions.py +6 -3
  82. vellum/workflows/workflows/base.py +3 -0
  83. {vellum_ai-1.2.3.dist-info → vellum_ai-1.2.5.dist-info}/METADATA +1 -1
  84. {vellum_ai-1.2.3.dist-info → vellum_ai-1.2.5.dist-info}/RECORD +96 -46
  85. vellum_cli/__init__.py +6 -0
  86. vellum_cli/config.py +2 -0
  87. vellum_cli/push.py +3 -0
  88. vellum_cli/tests/test_pull.py +2 -0
  89. vellum_cli/tests/test_push.py +39 -0
  90. vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py +2 -0
  91. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_mcp_serialization.py +1 -0
  92. vellum_ee/workflows/display/utils/events.py +19 -1
  93. vellum_ee/workflows/display/utils/tests/test_events.py +42 -0
  94. {vellum_ai-1.2.3.dist-info → vellum_ai-1.2.5.dist-info}/LICENSE +0 -0
  95. {vellum_ai-1.2.3.dist-info → vellum_ai-1.2.5.dist-info}/WHEEL +0 -0
  96. {vellum_ai-1.2.3.dist-info → vellum_ai-1.2.5.dist-info}/entry_points.txt +0 -0
@@ -1042,6 +1042,45 @@ def test_push__deploy_with_release_tags_success(mock_module, vellum_client):
1042
1042
  assert "Updated vellum.lock.json file." in result.output
1043
1043
 
1044
1044
 
1045
+ @pytest.mark.usefixtures("info_log_level")
1046
+ def test_push__deploy_with_release_description_success(mock_module, vellum_client):
1047
+ # GIVEN a single workflow configured
1048
+ temp_dir = mock_module.temp_dir
1049
+ module = mock_module.module
1050
+
1051
+ # AND a workflow exists in the module successfully
1052
+ _ensure_workflow_py(temp_dir, module)
1053
+
1054
+ # AND the push API call returns successfully
1055
+ workflow_deployment_id = str(uuid4())
1056
+ vellum_client.workflows.push.return_value = WorkflowPushResponse(
1057
+ workflow_sandbox_id=str(uuid4()),
1058
+ workflow_deployment_id=workflow_deployment_id,
1059
+ )
1060
+
1061
+ # WHEN calling `vellum workflows push` with --deploy and --release-description
1062
+ runner = CliRunner()
1063
+ result = runner.invoke(
1064
+ cli_main, ["workflows", "push", module, "--deploy", "--release-description", "This is a test release"]
1065
+ )
1066
+
1067
+ # THEN it should succeed
1068
+ assert result.exit_code == 0, result.output
1069
+
1070
+ # AND we should have called the push API with the correct deployment config
1071
+ vellum_client.workflows.push.assert_called_once()
1072
+ call_args = vellum_client.workflows.push.call_args.kwargs
1073
+
1074
+ # AND the deployment_config should contain the release description
1075
+ deployment_config_str = call_args["deployment_config"]
1076
+ deployment_config = json.loads(deployment_config_str)
1077
+ assert deployment_config["release_description"] == "This is a test release"
1078
+
1079
+ # AND should show success message
1080
+ assert "Successfully pushed" in result.output
1081
+ assert "Updated vellum.lock.json file." in result.output
1082
+
1083
+
1045
1084
  def test_push__deploy_stores_deployment_config_in_lock_file(mock_module, vellum_client):
1046
1085
  # GIVEN a single workflow
1047
1086
  temp_dir = mock_module.temp_dir
@@ -191,6 +191,7 @@ def test_serialize_node__tool_calling_node__mcp_server_api_key():
191
191
  {
192
192
  "type": "MCP_SERVER",
193
193
  "name": "my-mcp-server",
194
+ "description": "",
194
195
  "url": "https://my-mcp-server.com",
195
196
  "authorization_type": "API_KEY",
196
197
  "bearer_token_value": None,
@@ -243,6 +244,7 @@ def test_serialize_node__tool_calling_node__mcp_server_no_authorization():
243
244
  {
244
245
  "type": "MCP_SERVER",
245
246
  "name": "my-mcp-server",
247
+ "description": "",
246
248
  "url": "https://my-mcp-server.com",
247
249
  "authorization_type": None,
248
250
  "bearer_token_value": None,
@@ -52,6 +52,7 @@ def test_serialize_workflow():
52
52
  {
53
53
  "type": "MCP_SERVER",
54
54
  "name": "github",
55
+ "description": "",
55
56
  "url": "https://api.githubcopilot.com/mcp/",
56
57
  "authorization_type": "BEARER_TOKEN",
57
58
  "bearer_token_value": "GITHUB_PERSONAL_ACCESS_TOKEN",
@@ -7,6 +7,24 @@ from vellum_ee.workflows.display.utils.registry import (
7
7
  from vellum_ee.workflows.display.workflows.get_vellum_workflow_display_class import get_workflow_display
8
8
 
9
9
 
10
+ def _should_mark_workflow_dynamic(event: WorkflowExecutionInitiatedEvent) -> bool:
11
+ """
12
+ Check if workflow should be marked as dynamic based on execution context.
13
+ Returns True if parent.type == WORKFLOW_RELEASE_TAG and parent.parent.type == WORKFLOW_NODE.
14
+ """
15
+ if not event.parent:
16
+ return False
17
+
18
+ parent = event.parent
19
+ if parent.type != "WORKFLOW_RELEASE_TAG":
20
+ return False
21
+
22
+ if not parent.parent or parent.parent.type != "WORKFLOW_NODE":
23
+ return False
24
+
25
+ return True
26
+
27
+
10
28
  def event_enricher(event: WorkflowExecutionInitiatedEvent) -> WorkflowExecutionInitiatedEvent:
11
29
  workflow_definition = event.body.workflow_definition
12
30
  workflow_display = get_workflow_display(
@@ -16,7 +34,7 @@ def event_enricher(event: WorkflowExecutionInitiatedEvent) -> WorkflowExecutionI
16
34
  )
17
35
  register_workflow_display_context(event.span_id, workflow_display.display_context)
18
36
 
19
- if event.body.workflow_definition.is_dynamic:
37
+ if event.body.workflow_definition.is_dynamic or _should_mark_workflow_dynamic(event):
20
38
  register_workflow_display_class(workflow_definition, workflow_display.__class__)
21
39
  workflow_version_exec_config = workflow_display.serialize()
22
40
  setattr(event.body, "workflow_version_exec_config", workflow_version_exec_config)
@@ -2,8 +2,10 @@ import pytest
2
2
  from uuid import uuid4
3
3
  from typing import Optional
4
4
 
5
+ from vellum.workflows.events.types import NodeParentContext, WorkflowDeploymentParentContext
5
6
  from vellum.workflows.events.workflow import WorkflowExecutionInitiatedBody, WorkflowExecutionInitiatedEvent
6
7
  from vellum.workflows.inputs.base import BaseInputs
8
+ from vellum.workflows.outputs.base import BaseOutputs
7
9
  from vellum.workflows.workflows.base import BaseWorkflow
8
10
  from vellum_ee.workflows.display.utils.events import event_enricher
9
11
 
@@ -67,3 +69,43 @@ def test_event_enricher_static_workflow(is_dynamic: bool, expected_config: Optio
67
69
 
68
70
  # AND workflow_version_exec_config is set to the expected config
69
71
  assert event.body.workflow_version_exec_config == expected_config
72
+
73
+
74
+ def test_event_enricher_marks_subworkflow_deployment_as_dynamic():
75
+ """Test that event_enricher treats subworkflow deployments as dynamic."""
76
+
77
+ class TestWorkflow(BaseWorkflow):
78
+ is_dynamic = False
79
+
80
+ class Outputs(BaseOutputs):
81
+ pass
82
+
83
+ event: WorkflowExecutionInitiatedEvent = WorkflowExecutionInitiatedEvent(
84
+ trace_id=uuid4(),
85
+ span_id=uuid4(),
86
+ parent=WorkflowDeploymentParentContext(
87
+ span_id=uuid4(),
88
+ deployment_id=uuid4(),
89
+ deployment_name="test-deployment",
90
+ deployment_history_item_id=uuid4(),
91
+ release_tag_id=uuid4(),
92
+ release_tag_name="test-tag",
93
+ workflow_version_id=uuid4(),
94
+ external_id=None,
95
+ metadata=None,
96
+ parent=NodeParentContext(
97
+ span_id=uuid4(),
98
+ node_definition=TestWorkflow,
99
+ parent=None,
100
+ ),
101
+ ),
102
+ body=WorkflowExecutionInitiatedBody(
103
+ workflow_definition=TestWorkflow,
104
+ inputs=BaseInputs(),
105
+ ),
106
+ )
107
+
108
+ enriched_event = event_enricher(event)
109
+
110
+ assert hasattr(enriched_event.body, "workflow_version_exec_config")
111
+ assert enriched_event.body.workflow_version_exec_config is not None