vellum-ai 1.3.9__py3-none-any.whl → 1.3.11__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 (27) hide show
  1. vellum/client/core/client_wrapper.py +2 -2
  2. vellum/client/tests/__init__.py +0 -0
  3. vellum/client/tests/test_utils.py +34 -0
  4. vellum/client/types/variable_prompt_block.py +7 -0
  5. vellum/client/utils.py +24 -0
  6. vellum/workflows/__init__.py +2 -0
  7. vellum/workflows/errors/types.py +4 -1
  8. vellum/workflows/events/tests/test_event.py +1 -0
  9. vellum/workflows/exceptions.py +11 -2
  10. vellum/workflows/inputs/__init__.py +2 -0
  11. vellum/workflows/inputs/dataset_row.py +38 -0
  12. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +13 -1
  13. vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py +2 -0
  14. vellum/workflows/nodes/displayable/tool_calling_node/node.py +2 -3
  15. vellum/workflows/nodes/displayable/tool_calling_node/utils.py +2 -37
  16. vellum/workflows/sandbox.py +6 -2
  17. vellum/workflows/tests/test_dataset_row.py +99 -0
  18. vellum/workflows/types/definition.py +49 -2
  19. vellum/workflows/utils/functions.py +40 -1
  20. {vellum_ai-1.3.9.dist-info → vellum_ai-1.3.11.dist-info}/METADATA +1 -1
  21. {vellum_ai-1.3.9.dist-info → vellum_ai-1.3.11.dist-info}/RECORD +27 -22
  22. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py +1 -1
  23. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py +1 -1
  24. vellum_ee/workflows/display/utils/expressions.py +2 -23
  25. {vellum_ai-1.3.9.dist-info → vellum_ai-1.3.11.dist-info}/LICENSE +0 -0
  26. {vellum_ai-1.3.9.dist-info → vellum_ai-1.3.11.dist-info}/WHEEL +0 -0
  27. {vellum_ai-1.3.9.dist-info → vellum_ai-1.3.11.dist-info}/entry_points.txt +0 -0
@@ -27,10 +27,10 @@ class BaseClientWrapper:
27
27
 
28
28
  def get_headers(self) -> typing.Dict[str, str]:
29
29
  headers: typing.Dict[str, str] = {
30
- "User-Agent": "vellum-ai/1.3.9",
30
+ "User-Agent": "vellum-ai/1.3.11",
31
31
  "X-Fern-Language": "Python",
32
32
  "X-Fern-SDK-Name": "vellum-ai",
33
- "X-Fern-SDK-Version": "1.3.9",
33
+ "X-Fern-SDK-Version": "1.3.11",
34
34
  **(self.get_custom_headers() or {}),
35
35
  }
36
36
  if self._api_version is not None:
File without changes
@@ -0,0 +1,34 @@
1
+ import uuid
2
+ from unittest.mock import Mock
3
+ from vellum.client.utils import convert_input_variable_to_uuid
4
+
5
+
6
+ def test_convert_input_variable_to_uuid_with_valid_uuid():
7
+ """Test convert_input_variable_to_uuid with valid UUID passes through unchanged."""
8
+ uuid_value = "123e4567-e89b-12d3-a456-426614174000"
9
+
10
+ # GIVEN a valid UUID
11
+ # WHEN the function is called
12
+ result = convert_input_variable_to_uuid(uuid_value)
13
+
14
+ # THEN the result should be the original UUID unchanged
15
+ assert result == uuid_value
16
+
17
+
18
+ def test_convert_input_variable_to_uuid_with_invalid_uuid_converts():
19
+ """Test convert_input_variable_to_uuid with invalid UUID gets converted to UUID."""
20
+ non_uuid_value = "some_variable_name"
21
+ executable_id = "test_executable_123"
22
+
23
+ # GIVEN an invalid UUID with context
24
+ mock_info = Mock()
25
+ mock_info.context = {"executable_id": executable_id}
26
+
27
+ # WHEN the function is called
28
+ result = convert_input_variable_to_uuid(non_uuid_value, mock_info)
29
+
30
+ # THEN it should return a different value
31
+ assert result != non_uuid_value
32
+
33
+ # AND it's a valid UUID
34
+ uuid.UUID(result) # This will raise ValueError if not a valid UUID
@@ -3,6 +3,7 @@
3
3
  import typing
4
4
 
5
5
  import pydantic
6
+ from vellum.client.utils import convert_input_variable_to_uuid
6
7
  from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
8
  from .ephemeral_prompt_cache_config import EphemeralPromptCacheConfig
8
9
  from .prompt_block_state import PromptBlockState
@@ -26,3 +27,9 @@ class VariablePromptBlock(UniversalBaseModel):
26
27
  frozen = True
27
28
  smart_union = True
28
29
  extra = pydantic.Extra.allow
30
+
31
+
32
+ @pydantic.field_serializer("input_variable")
33
+ def serialize_input_variable(self, value: str, info: pydantic.SerializationInfo) -> str:
34
+ """Convert input_variable to UUID using executable_id from context."""
35
+ return convert_input_variable_to_uuid(value, info)
vellum/client/utils.py ADDED
@@ -0,0 +1,24 @@
1
+ # Custom client utilities
2
+ # This file is not generated by Fern and can be freely edited
3
+
4
+ from uuid import UUID
5
+ from typing import Optional
6
+ from pydantic import SerializationInfo
7
+
8
+
9
+ def convert_input_variable_to_uuid(value: str, info: Optional[SerializationInfo] = None) -> str:
10
+ """Convert input_variable to UUID using executable_id from context."""
11
+ # Check if value is already a valid UUID
12
+ try:
13
+ UUID(value)
14
+ return value # Already a UUID, return as-is
15
+ except ValueError:
16
+ pass # Not a UUID, continue with conversion logic
17
+
18
+ if info and hasattr(info, "context") and info.context:
19
+ executable_id = info.context.get("executable_id")
20
+ if executable_id:
21
+ from vellum.workflows.utils.uuids import uuid4_from_hash # avoid circular import
22
+
23
+ return str(uuid4_from_hash(f"{executable_id}|{value}"))
24
+ return value
@@ -1,5 +1,7 @@
1
+ from .inputs.dataset_row import DatasetRow
1
2
  from .workflows import BaseWorkflow
2
3
 
3
4
  __all__ = [
4
5
  "BaseWorkflow",
6
+ "DatasetRow",
5
7
  ]
@@ -1,7 +1,7 @@
1
1
  from dataclasses import dataclass
2
2
  from enum import Enum
3
3
  import logging
4
- from typing import Any, Dict
4
+ from typing import Any, Dict, Optional
5
5
 
6
6
  from vellum.client.types.vellum_error import VellumError
7
7
  from vellum.client.types.vellum_error_code_enum import VellumErrorCodeEnum
@@ -30,6 +30,7 @@ class WorkflowErrorCode(Enum):
30
30
  class WorkflowError:
31
31
  message: str
32
32
  code: WorkflowErrorCode
33
+ raw_data: Optional[Dict[str, Any]] = None
33
34
 
34
35
  def __contains__(self, item: Any) -> bool:
35
36
  return item in self.message
@@ -39,6 +40,7 @@ _VELLUM_ERROR_CODE_TO_WORKFLOW_ERROR_CODE: Dict[VellumErrorCodeEnum, WorkflowErr
39
40
  "INVALID_REQUEST": WorkflowErrorCode.INVALID_INPUTS,
40
41
  "INVALID_INPUTS": WorkflowErrorCode.INVALID_INPUTS,
41
42
  "PROVIDER_ERROR": WorkflowErrorCode.PROVIDER_ERROR,
43
+ "PROVIDER_CREDENTIALS_UNAVAILABLE": WorkflowErrorCode.PROVIDER_CREDENTIALS_UNAVAILABLE,
42
44
  "REQUEST_TIMEOUT": WorkflowErrorCode.PROVIDER_ERROR,
43
45
  "INTERNAL_SERVER_ERROR": WorkflowErrorCode.INTERNAL_ERROR,
44
46
  "USER_DEFINED_ERROR": WorkflowErrorCode.USER_DEFINED_ERROR,
@@ -55,6 +57,7 @@ def vellum_error_to_workflow_error(error: VellumError) -> WorkflowError:
55
57
  return WorkflowError(
56
58
  message=error.message,
57
59
  code=workflow_error_code,
60
+ raw_data=error.raw_data or {},
58
61
  )
59
62
 
60
63
 
@@ -260,6 +260,7 @@ mock_node_uuid = str(uuid4_from_hash(MockNode.__qualname__))
260
260
  "error": {
261
261
  "message": "Workflow failed",
262
262
  "code": "USER_DEFINED_ERROR",
263
+ "raw_data": None,
263
264
  },
264
265
  "stacktrace": None,
265
266
  },
@@ -1,10 +1,18 @@
1
+ from typing import Any, Dict, Optional
2
+
1
3
  from vellum.workflows.errors import WorkflowError, WorkflowErrorCode
2
4
 
3
5
 
4
6
  class NodeException(Exception):
5
- def __init__(self, message: str, code: WorkflowErrorCode = WorkflowErrorCode.INTERNAL_ERROR):
7
+ def __init__(
8
+ self,
9
+ message: str,
10
+ code: WorkflowErrorCode = WorkflowErrorCode.INTERNAL_ERROR,
11
+ raw_data: Optional[Dict[str, Any]] = None,
12
+ ):
6
13
  self.message = message
7
14
  self.code = code
15
+ self.raw_data = raw_data
8
16
  super().__init__(message)
9
17
 
10
18
  @property
@@ -12,11 +20,12 @@ class NodeException(Exception):
12
20
  return WorkflowError(
13
21
  message=self.message,
14
22
  code=self.code,
23
+ raw_data=self.raw_data,
15
24
  )
16
25
 
17
26
  @staticmethod
18
27
  def of(workflow_error: WorkflowError) -> "NodeException":
19
- return NodeException(message=workflow_error.message, code=workflow_error.code)
28
+ return NodeException(message=workflow_error.message, code=workflow_error.code, raw_data=workflow_error.raw_data)
20
29
 
21
30
 
22
31
  class WorkflowInitializationException(Exception):
@@ -1,5 +1,7 @@
1
1
  from .base import BaseInputs
2
+ from .dataset_row import DatasetRow
2
3
 
3
4
  __all__ = [
4
5
  "BaseInputs",
6
+ "DatasetRow",
5
7
  ]
@@ -0,0 +1,38 @@
1
+ from typing import Any, Dict
2
+
3
+ from pydantic import field_serializer
4
+
5
+ from vellum.client.core.pydantic_utilities import UniversalBaseModel
6
+ from vellum.workflows.inputs.base import BaseInputs
7
+
8
+
9
+ class DatasetRow(UniversalBaseModel):
10
+ """
11
+ Universal base model representing a dataset row with a label and inputs.
12
+
13
+ Attributes:
14
+ label: String label for the dataset row
15
+ inputs: BaseInputs instance containing the input data
16
+ """
17
+
18
+ label: str
19
+ inputs: BaseInputs
20
+
21
+ @field_serializer("inputs")
22
+ def serialize_inputs(self, inputs: BaseInputs) -> Dict[str, Any]:
23
+ """
24
+ Custom serializer for BaseInputs that converts it to a dictionary.
25
+
26
+ Args:
27
+ inputs: BaseInputs instance to serialize
28
+
29
+ Returns:
30
+ Dictionary representation of the inputs
31
+ """
32
+ result = {}
33
+
34
+ for input_descriptor, value in inputs:
35
+ if not input_descriptor.name.startswith("__"):
36
+ result[input_descriptor.name] = value
37
+
38
+ return result
@@ -45,12 +45,14 @@ from vellum.workflows.nodes.displayable.bases.base_prompt_node import BasePrompt
45
45
  from vellum.workflows.nodes.displayable.bases.utils import process_additional_prompt_outputs
46
46
  from vellum.workflows.outputs import BaseOutput
47
47
  from vellum.workflows.types import MergeBehavior
48
- from vellum.workflows.types.definition import DeploymentDefinition
48
+ from vellum.workflows.types.definition import DeploymentDefinition, MCPServer
49
49
  from vellum.workflows.types.generics import StateType, is_workflow_class
50
50
  from vellum.workflows.utils.functions import (
51
51
  compile_function_definition,
52
52
  compile_inline_workflow_function_definition,
53
+ compile_mcp_tool_definition,
53
54
  compile_workflow_deployment_function_definition,
55
+ get_mcp_tool_name,
54
56
  )
55
57
  from vellum.workflows.utils.pydantic_schema import normalize_json
56
58
 
@@ -140,6 +142,16 @@ class BaseInlinePromptNode(BasePromptNode[StateType], Generic[StateType]):
140
142
  normalized_functions.append(compile_inline_workflow_function_definition(function))
141
143
  elif callable(function):
142
144
  normalized_functions.append(compile_function_definition(function))
145
+ elif isinstance(function, MCPServer):
146
+ tool_definitions = compile_mcp_tool_definition(function)
147
+ for tool_def in tool_definitions:
148
+ normalized_functions.append(
149
+ FunctionDefinition(
150
+ name=get_mcp_tool_name(tool_def),
151
+ description=tool_def.description,
152
+ parameters=tool_def.parameters,
153
+ )
154
+ )
143
155
  else:
144
156
  raise NodeException(
145
157
  message=f"`{function}` is not a valid function definition",
@@ -114,6 +114,7 @@ def test_inline_text_prompt_node__catch_provider_error(vellum_adhoc_prompt_clien
114
114
  expected_error = VellumError(
115
115
  message="OpenAI failed",
116
116
  code="PROVIDER_ERROR",
117
+ raw_data={"type": "ERROR", "error": {"message": "Something went wrong"}},
117
118
  )
118
119
 
119
120
  def generate_prompt_events(*args: Any, **kwargs: Any) -> Iterator[ExecutePromptEvent]:
@@ -144,6 +145,7 @@ def test_inline_text_prompt_node__catch_provider_error(vellum_adhoc_prompt_clien
144
145
  value=SdkVellumError(
145
146
  message="OpenAI failed",
146
147
  code=WorkflowErrorCode.PROVIDER_ERROR,
148
+ raw_data={"type": "ERROR", "error": {"message": "Something went wrong"}},
147
149
  ),
148
150
  )
149
151
  in outputs
@@ -18,14 +18,13 @@ from vellum.workflows.nodes.displayable.tool_calling_node.utils import (
18
18
  create_router_node,
19
19
  create_tool_prompt_node,
20
20
  get_function_name,
21
- get_mcp_tool_name,
22
- hydrate_mcp_tool_definitions,
23
21
  )
24
22
  from vellum.workflows.outputs.base import BaseOutput, BaseOutputs
25
23
  from vellum.workflows.state.context import WorkflowContext
26
24
  from vellum.workflows.types.core import EntityInputsInterface, Tool
27
25
  from vellum.workflows.types.definition import MCPServer
28
26
  from vellum.workflows.types.generics import StateType
27
+ from vellum.workflows.utils.functions import compile_mcp_tool_definition, get_mcp_tool_name
29
28
  from vellum.workflows.workflows.event_filters import all_workflow_event_filter
30
29
 
31
30
 
@@ -162,7 +161,7 @@ class ToolCallingNode(BaseNode[StateType], Generic[StateType]):
162
161
  self._function_nodes = {}
163
162
  for function in self.functions:
164
163
  if isinstance(function, MCPServer):
165
- tool_definitions = hydrate_mcp_tool_definitions(function)
164
+ tool_definitions = compile_mcp_tool_definition(function)
166
165
  for tool_definition in tool_definitions:
167
166
  function_name = get_mcp_tool_name(tool_definition)
168
167
 
@@ -33,6 +33,7 @@ from vellum.workflows.state.encoder import DefaultStateEncoder
33
33
  from vellum.workflows.types.core import EntityInputsInterface, MergeBehavior, Tool, ToolBase
34
34
  from vellum.workflows.types.definition import ComposioToolDefinition, DeploymentDefinition, MCPServer, MCPToolDefinition
35
35
  from vellum.workflows.types.generics import is_workflow_class
36
+ from vellum.workflows.utils.functions import compile_mcp_tool_definition, get_mcp_tool_name
36
37
 
37
38
  CHAT_HISTORY_VARIABLE = "chat_history"
38
39
 
@@ -303,26 +304,6 @@ def _hydrate_composio_tool_definition(tool_def: ComposioToolDefinition) -> Funct
303
304
  )
304
305
 
305
306
 
306
- def hydrate_mcp_tool_definitions(server_def: MCPServer) -> List[MCPToolDefinition]:
307
- """Hydrate an MCPToolDefinition with detailed information from the MCP server.
308
-
309
- We do tool discovery on the MCP server to get the tool definitions.
310
-
311
- Args:
312
- tool_def: The basic MCPToolDefinition to enhance
313
-
314
- Returns:
315
- MCPToolDefinition with detailed parameters and description
316
- """
317
- try:
318
- mcp_service = MCPService()
319
- return mcp_service.hydrate_tool_definitions(server_def)
320
- except Exception as e:
321
- # If hydration fails, log and return original
322
- logger.warning(f"Failed to enhance MCP server '{server_def.name}': {e}")
323
- return []
324
-
325
-
326
307
  def create_tool_prompt_node(
327
308
  ml_model: str,
328
309
  blocks: List[Union[PromptBlock, Dict[str, Any]]],
@@ -341,17 +322,6 @@ def create_tool_prompt_node(
341
322
  # Get Composio tool details and hydrate the function definition
342
323
  enhanced_function = _hydrate_composio_tool_definition(function)
343
324
  prompt_functions.append(enhanced_function)
344
- elif isinstance(function, MCPServer):
345
- tool_functions: List[MCPToolDefinition] = hydrate_mcp_tool_definitions(function)
346
- for tool_function in tool_functions:
347
- name = get_mcp_tool_name(tool_function)
348
- prompt_functions.append(
349
- FunctionDefinition(
350
- name=name,
351
- description=tool_function.description,
352
- parameters=tool_function.parameters,
353
- )
354
- )
355
325
  else:
356
326
  prompt_functions.append(function)
357
327
  else:
@@ -440,7 +410,7 @@ def create_router_node(
440
410
  port = create_port_condition(function_name)
441
411
  setattr(Ports, function_name, port)
442
412
  elif isinstance(function, MCPServer):
443
- tool_functions: List[MCPToolDefinition] = hydrate_mcp_tool_definitions(function)
413
+ tool_functions: List[MCPToolDefinition] = compile_mcp_tool_definition(function)
444
414
  for tool_function in tool_functions:
445
415
  name = get_mcp_tool_name(tool_function)
446
416
  port = create_port_condition(name)
@@ -604,8 +574,3 @@ def get_function_name(function: ToolBase) -> str:
604
574
  return function.name # type: ignore[return-value]
605
575
  else:
606
576
  return snake_case(function.__name__)
607
-
608
-
609
- def get_mcp_tool_name(tool_def: MCPToolDefinition) -> str:
610
- server_name = snake_case(tool_def.server.name)
611
- return f"{server_name}__{tool_def.name}"
@@ -1,9 +1,10 @@
1
- from typing import Generic, Optional, Sequence
1
+ from typing import Generic, Optional, Sequence, Union
2
2
 
3
3
  import dotenv
4
4
 
5
5
  from vellum.workflows.events.workflow import WorkflowEventStream
6
6
  from vellum.workflows.inputs.base import BaseInputs
7
+ from vellum.workflows.inputs.dataset_row import DatasetRow
7
8
  from vellum.workflows.logging import load_logger
8
9
  from vellum.workflows.types.generics import WorkflowType
9
10
  from vellum.workflows.workflows.event_filters import root_workflow_event_filter
@@ -14,7 +15,7 @@ class WorkflowSandboxRunner(Generic[WorkflowType]):
14
15
  self,
15
16
  workflow: WorkflowType,
16
17
  inputs: Optional[Sequence[BaseInputs]] = None, # DEPRECATED - remove in v2.0.0
17
- dataset: Optional[Sequence[BaseInputs]] = None,
18
+ dataset: Optional[Sequence[Union[BaseInputs, DatasetRow]]] = None,
18
19
  ):
19
20
  dotenv.load_dotenv()
20
21
  self._logger = load_logger()
@@ -50,6 +51,9 @@ class WorkflowSandboxRunner(Generic[WorkflowType]):
50
51
 
51
52
  selected_inputs = self._inputs[index]
52
53
 
54
+ if isinstance(selected_inputs, DatasetRow):
55
+ selected_inputs = selected_inputs.inputs
56
+
53
57
  events = self._workflow.stream(
54
58
  inputs=selected_inputs,
55
59
  event_filter=root_workflow_event_filter,
@@ -0,0 +1,99 @@
1
+ from typing import Optional
2
+
3
+ from vellum.client.types.chat_message import ChatMessage
4
+ from vellum.workflows.inputs.base import BaseInputs
5
+ from vellum.workflows.inputs.dataset_row import DatasetRow
6
+
7
+
8
+ def test_dataset_row_serialization():
9
+ """
10
+ Test that DatasetRow can be properly serialized to JSON and back.
11
+ """
12
+
13
+ class TestInputs(BaseInputs):
14
+ message: str
15
+ count: int
16
+ optional_field: Optional[str] = None
17
+ chat_history: list[ChatMessage]
18
+
19
+ test_inputs = TestInputs(
20
+ message="Hello World",
21
+ count=42,
22
+ optional_field="test",
23
+ chat_history=[ChatMessage(text="Hello", role="USER"), ChatMessage(text="Hi there!", role="ASSISTANT")],
24
+ )
25
+ dataset_row = DatasetRow(label="test_label", inputs=test_inputs)
26
+
27
+ serialized_dict = dataset_row.model_dump()
28
+
29
+ assert "label" in serialized_dict
30
+ assert "inputs" in serialized_dict
31
+ assert serialized_dict["label"] == "test_label"
32
+
33
+ inputs_data = serialized_dict["inputs"]
34
+ assert inputs_data["message"] == "Hello World"
35
+ assert inputs_data["count"] == 42
36
+ assert inputs_data["optional_field"] == "test"
37
+ assert "chat_history" in inputs_data
38
+ assert len(inputs_data["chat_history"]) == 2
39
+ assert inputs_data["chat_history"][0]["text"] == "Hello"
40
+ assert inputs_data["chat_history"][0]["role"] == "USER"
41
+ assert inputs_data["chat_history"][1]["text"] == "Hi there!"
42
+ assert inputs_data["chat_history"][1]["role"] == "ASSISTANT"
43
+
44
+
45
+ def test_dataset_row_dict_serialization():
46
+ """
47
+ Test that DatasetRow can be properly converted to dict.
48
+ """
49
+
50
+ class SimpleInputs(BaseInputs):
51
+ text: str
52
+
53
+ simple_inputs = SimpleInputs(text="sample text")
54
+ dataset_row = DatasetRow(label="simple_label", inputs=simple_inputs)
55
+
56
+ result_dict = dataset_row.model_dump()
57
+
58
+ assert result_dict["label"] == "simple_label"
59
+ assert result_dict["inputs"]["text"] == "sample text"
60
+
61
+
62
+ def test_dataset_row_with_multiple_fields():
63
+ """
64
+ Test that DatasetRow works with BaseInputs that have multiple fields.
65
+ """
66
+
67
+ class MultiFieldInputs(BaseInputs):
68
+ text_field: str
69
+ number_field: int
70
+ optional_field: Optional[str] = None
71
+
72
+ multi_inputs = MultiFieldInputs(text_field="test_text", number_field=456, optional_field="optional_value")
73
+ dataset_row = DatasetRow(label="multi_field_test", inputs=multi_inputs)
74
+
75
+ result_dict = dataset_row.model_dump()
76
+
77
+ assert result_dict["label"] == "multi_field_test"
78
+ assert result_dict["inputs"]["text_field"] == "test_text"
79
+ assert result_dict["inputs"]["number_field"] == 456
80
+ assert result_dict["inputs"]["optional_field"] == "optional_value"
81
+
82
+
83
+ def test_dataset_row_with_default_inputs():
84
+ """
85
+ Test that DatasetRow works with BaseInputs that have default values.
86
+ """
87
+
88
+ class InputsWithDefaults(BaseInputs):
89
+ required_field: str
90
+ optional_with_default: str = "default_value"
91
+
92
+ inputs_with_defaults = InputsWithDefaults(required_field="required_value")
93
+ dataset_row = DatasetRow(label="defaults_test", inputs=inputs_with_defaults)
94
+
95
+ serialized_dict = dataset_row.model_dump()
96
+
97
+ assert serialized_dict["label"] == "defaults_test"
98
+ assert serialized_dict["inputs"]["required_field"] == "required_value"
99
+ assert serialized_dict["inputs"]["optional_with_default"] == "default_value"
@@ -2,12 +2,14 @@ import importlib
2
2
  import inspect
3
3
  from types import FrameType
4
4
  from uuid import UUID
5
- from typing import Annotated, Any, Dict, Literal, Optional, Union
5
+ from typing import Annotated, Any, Dict, List, Literal, Optional, Union
6
6
 
7
- from pydantic import BeforeValidator
7
+ from pydantic import BeforeValidator, SerializationInfo, model_serializer
8
8
 
9
+ from vellum import Vellum
9
10
  from vellum.client.core.pydantic_utilities import UniversalBaseModel
10
11
  from vellum.client.types.code_resource_definition import CodeResourceDefinition as ClientCodeResourceDefinition
12
+ from vellum.client.types.vellum_variable import VellumVariable
11
13
  from vellum.workflows.constants import AuthorizationType
12
14
  from vellum.workflows.references.environment_variable import EnvironmentVariableReference
13
15
 
@@ -78,6 +80,11 @@ class DeploymentDefinition(UniversalBaseModel):
78
80
  deployment: str
79
81
  release_tag: str = "LATEST"
80
82
 
83
+ # hydrated fields
84
+ name: Optional[str] = None
85
+ description: Optional[str] = None
86
+ input_variables: Optional[List[VellumVariable]] = None
87
+
81
88
  def _is_uuid(self) -> bool:
82
89
  """Check if the deployment field is a valid UUID."""
83
90
  try:
@@ -100,6 +107,46 @@ class DeploymentDefinition(UniversalBaseModel):
100
107
  return self.deployment
101
108
  return None
102
109
 
110
+ def get_release_info(self, client: Vellum):
111
+ try:
112
+ release = client.workflow_deployments.retrieve_workflow_deployment_release(
113
+ self.deployment, self.release_tag
114
+ )
115
+ except Exception:
116
+ # If we fail to get the release info, we'll use the deployment name and description
117
+ return {
118
+ "name": self.deployment,
119
+ "description": f"Workflow Deployment for {self.deployment}",
120
+ "input_variables": [],
121
+ }
122
+
123
+ return {
124
+ "name": release.deployment.name,
125
+ "description": release.description or f"Workflow Deployment for {self.deployment}",
126
+ "input_variables": release.workflow_version.input_variables,
127
+ }
128
+
129
+ @model_serializer(mode="wrap")
130
+ def _serialize(self, handler, info: SerializationInfo):
131
+ """Allow Pydantic to serialize directly given a `client` in context.
132
+
133
+ Falls back to the default serialization when client is not provided.
134
+ """
135
+ context = info.context if info and hasattr(info, "context") else {}
136
+ client: Optional[Vellum] = context.get("client") if context else None
137
+
138
+ if client:
139
+ release_info = self.get_release_info(client)
140
+ return {
141
+ "type": "WORKFLOW_DEPLOYMENT",
142
+ "name": release_info["name"],
143
+ "description": release_info["description"],
144
+ "deployment": self.deployment,
145
+ "release_tag": self.release_tag,
146
+ }
147
+
148
+ return handler(self)
149
+
103
150
 
104
151
  class ComposioToolDefinition(UniversalBaseModel):
105
152
  """Represents a specific Composio action that can be used in Tool Calling Node"""
@@ -1,6 +1,19 @@
1
1
  import dataclasses
2
2
  import inspect
3
- from typing import TYPE_CHECKING, Annotated, Any, Callable, Dict, Literal, Optional, Type, Union, get_args, get_origin
3
+ from typing import (
4
+ TYPE_CHECKING,
5
+ Annotated,
6
+ Any,
7
+ Callable,
8
+ Dict,
9
+ List,
10
+ Literal,
11
+ Optional,
12
+ Type,
13
+ Union,
14
+ get_args,
15
+ get_origin,
16
+ )
4
17
 
5
18
  from pydantic import BaseModel
6
19
  from pydantic_core import PydanticUndefined
@@ -8,6 +21,8 @@ from pydash import snake_case
8
21
 
9
22
  from vellum import Vellum
10
23
  from vellum.client.types.function_definition import FunctionDefinition
24
+ from vellum.workflows.integrations.mcp_service import MCPService
25
+ from vellum.workflows.types.definition import MCPServer, MCPToolDefinition
11
26
  from vellum.workflows.utils.vellum_variables import vellum_variable_type_to_openapi_type
12
27
 
13
28
  if TYPE_CHECKING:
@@ -261,6 +276,30 @@ def compile_workflow_deployment_function_definition(
261
276
  )
262
277
 
263
278
 
279
+ def get_mcp_tool_name(tool_def: MCPToolDefinition) -> str:
280
+ """Generate a unique name for an MCP tool by combining server and tool names."""
281
+ server_name = snake_case(tool_def.server.name)
282
+ return f"{server_name}__{tool_def.name}"
283
+
284
+
285
+ def compile_mcp_tool_definition(server_def: MCPServer) -> List[MCPToolDefinition]:
286
+ """Hydrate an MCPToolDefinition with detailed information from the MCP server.
287
+
288
+ We do tool discovery on the MCP server to get the tool definitions.
289
+
290
+ Args:
291
+ tool_def: The basic MCPToolDefinition to enhance
292
+
293
+ Returns:
294
+ MCPToolDefinition with detailed parameters and description
295
+ """
296
+ try:
297
+ mcp_service = MCPService()
298
+ return mcp_service.hydrate_tool_definitions(server_def)
299
+ except Exception:
300
+ return []
301
+
302
+
264
303
  def use_tool_inputs(**inputs):
265
304
  """
266
305
  Decorator to specify which parameters of a tool function should be provided
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 1.3.9
3
+ Version: 1.3.11
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0
@@ -98,10 +98,10 @@ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_
98
98
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py,sha256=ddPa8gNBYH2tWk92ymngY7M8n74J-8CEre50HISP_-g,7877
99
99
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py,sha256=A7Ef8P1-Nyvsb97bumKT9W2R1LuZaY9IKFV-7iRueog,4010
100
100
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_composio_serialization.py,sha256=oVXCjkU0G56QJmqnd_xIwF3D9bhJwALFibM2wmRhwUk,3739
101
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py,sha256=1GiF3XgJ85vE05_nZFo66snNuqTt0p1c22gNI9c_BXY,26442
101
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py,sha256=UD1HU8aEAXSo43JGhjBGE2FGsknHj_zOsIHTo2TLEW0,26470
102
102
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_mcp_serialization.py,sha256=QhQbijeCnFeX1i3SMjHJg2WVAEt5JEO3dhFRv-mofdA,2458
103
103
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_parent_input.py,sha256=__LX4cuzbyZp_1wc-SI8X_J0tnhOkCEmRVUWLKI5aQM,4578
104
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py,sha256=VB5c6U0GRUxPm9FbzgKYIpoZfoIU9szAWUQJ5L-4Lug,10187
104
+ vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py,sha256=tyRlb6ozcsvkeHOC9dsHc4jg3HrHQITDGadi8qbNGns,10215
105
105
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_workflow_deployment_serialization.py,sha256=XIZZr5POo2NLn2uEWm9EC3rejeBMoO4X-JtzTH6mvp4,4074
106
106
  vellum_ee/workflows/display/tests/workflow_serialization/test_basic_try_node_serialization.py,sha256=pLCyMScV88DTBXRH7jXaXOEA1GBq8NIipCUFwIAWnwI,2771
107
107
  vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py,sha256=exT7U-axwtYgFylagScflSQLJEND51qIAx2UATju6JM,6023
@@ -113,7 +113,7 @@ vellum_ee/workflows/display/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
113
113
  vellum_ee/workflows/display/utils/auto_layout.py,sha256=f4GiLn_LazweupfqTpubcdtdfE_vrOcmZudSsnYIY9E,3906
114
114
  vellum_ee/workflows/display/utils/events.py,sha256=DE33uoKW78BZtITJ6L22dMZN3KR1BuZBVC98C_gIyzU,1943
115
115
  vellum_ee/workflows/display/utils/exceptions.py,sha256=LSwwxCYNxFkf5XMUcFkaZKpQ13OSrI7y_bpEUwbKVk0,169
116
- vellum_ee/workflows/display/utils/expressions.py,sha256=UoZKiZy2Rhx5Hp2e2J2ipSdQCIQfkAOL_tIxHqLCrAM,20299
116
+ vellum_ee/workflows/display/utils/expressions.py,sha256=K_9CVZJkwkYtLEPwaOA3Sb0wMmi0KbmJUGNkpXsRSbE,19506
117
117
  vellum_ee/workflows/display/utils/registry.py,sha256=1qXiBTdsnro6FeCX0FGBEK7CIf6wa--Jt50iZ_nEp_M,3460
118
118
  vellum_ee/workflows/display/utils/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
119
  vellum_ee/workflows/display/utils/tests/test_auto_layout.py,sha256=vfXI769418s9vda5Gb5NFBH747WMOwSgHRXeLCTLVm8,2356
@@ -155,7 +155,7 @@ vellum/client/README.md,sha256=flqu57ubZNTfpq60CdLtJC9gp4WEkyjb_n_eZ4OYf9w,6497
155
155
  vellum/client/__init__.py,sha256=T5Ht_w-Mk_9nzGqdadhQB8V20M0vYj7am06ut0A3P1o,73401
156
156
  vellum/client/core/__init__.py,sha256=lTcqUPXcx4112yLDd70RAPeqq6tu3eFMe1pKOqkW9JQ,1562
157
157
  vellum/client/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
158
- vellum/client/core/client_wrapper.py,sha256=yiW8T6LXnqj5RVczNfHBZ2L3TMA_MWurdCwV6hFZPw8,2840
158
+ vellum/client/core/client_wrapper.py,sha256=jUohtsg67ju5RCuUUwRLdh1g44h86JtrmqbDsIJDNts,2842
159
159
  vellum/client/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
160
160
  vellum/client/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
161
161
  vellum/client/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
@@ -250,6 +250,8 @@ vellum/client/resources/workspace_secrets/raw_client.py,sha256=ZfiNd1NisolmK07QP
250
250
  vellum/client/resources/workspaces/__init__.py,sha256=_VhToAyIt_5axN6CLJwtxg3-CO7THa_23pbUzqhXJa4,85
251
251
  vellum/client/resources/workspaces/client.py,sha256=36KYa2FDu6h65q2GscUFOJs4qKeiOA6grOYoCc0Gi3E,2936
252
252
  vellum/client/resources/workspaces/raw_client.py,sha256=M3Ewk1ZfEZ44EeTvBtBNoNKi5whwfLY-1GR07SyfDTI,3517
253
+ vellum/client/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
254
+ vellum/client/tests/test_utils.py,sha256=zk8z45-2xrm9sZ2hq8PTqY8MXmXtPqMqYK0VBBX0GHg,1176
253
255
  vellum/client/types/__init__.py,sha256=ZzAl8sIsRT3hkRaCO_tlR9fjgVIM7sQCxmLO_S5WrIo,71915
254
256
  vellum/client/types/ad_hoc_execute_prompt_event.py,sha256=B69EesIH6fpNsdoiJaSG9zF1Sl17FnjoTu4CBkUSoHk,608
255
257
  vellum/client/types/ad_hoc_expand_meta.py,sha256=Kajcj3dKKed5e7uZibRnE3ZonK_bB2JPM-3aLjLfUp4,1295
@@ -794,7 +796,7 @@ vellum/client/types/token_overlapping_window_chunking_request.py,sha256=ez-hqu3q
794
796
  vellum/client/types/unit_enum.py,sha256=BKWRVp2WfHtGK4D6TsolhNJHGHfExzrRHkFn8H8QkwQ,113
795
797
  vellum/client/types/upload_document_response.py,sha256=C-JP0uAraD8waVwCNRM4FRCRglmv78m532gpy2Q9_Oc,613
796
798
  vellum/client/types/upsert_test_suite_test_case_request.py,sha256=VZGW1_Bw5cvU7RDg7MhT3A9C3ftyeYnAJaDMiil1FuQ,1978
797
- vellum/client/types/variable_prompt_block.py,sha256=417cXRq9V33iWTDWiX941VzOwhzfHvUHYPjgUev9Kf0,910
799
+ vellum/client/types/variable_prompt_block.py,sha256=sGLrhpDIj7ThxYZXvE3DsMGdQn-F2uoZ_GfTn-pMKjE,1255
798
800
  vellum/client/types/vellum_audio.py,sha256=rgL5GPBKDYk0PPQX_2XkerVERBxra9OR3k_PP57ruTc,685
799
801
  vellum/client/types/vellum_audio_request.py,sha256=vtkd49BVlLrY9UF3Yk52P5sDbtdY7sY9_XeMBU_VDm0,692
800
802
  vellum/client/types/vellum_code_resource_definition.py,sha256=XdueTR342BDjevZ3ktJJI99RqRED4A5SUOyzPt2K6us,661
@@ -915,6 +917,7 @@ vellum/client/types/workflow_sandbox_parent_context.py,sha256=8FJ8vq7CVTg-OnOXlb
915
917
  vellum/client/types/workflow_stream_event.py,sha256=6dQx_D-UPfJVrIsSW6krmZKDKeP9kPojFHDgqy_58io,362
916
918
  vellum/client/types/workspace_read.py,sha256=NAVouD25ZHvldLrAvAOwL2w2f1tqZaSC05wZ--YvBCQ,661
917
919
  vellum/client/types/workspace_secret_read.py,sha256=qWabw1u5HZpuv77kAwtAQigj4CDB41csJ2wmXu5eJS8,678
920
+ vellum/client/utils.py,sha256=b_ajWqSrXigPbUVOGTdzy_gL0iQo9r1OMUH8quuhjuA,885
918
921
  vellum/core/__init__.py,sha256=Iph1pJ7wkjHt7Xh1vUeLgMqFCNa0GYjtu3BhG8EhV8Y,136
919
922
  vellum/core/api_error.py,sha256=GDjkxQb8k4HqTthWpqwIVE7hLVXJQmRT8sip2mzB-8I,146
920
923
  vellum/core/client_wrapper.py,sha256=d3MqLPTOfMq8-AaHg3S7BkBczhyrbdpnkhR0FtOvV8A,151
@@ -1712,7 +1715,7 @@ vellum/utils/typing.py,sha256=wx_daFqD69cYkuJTVnvNrpjhqC3uuhbnyJ9_bIwC9OU,327
1712
1715
  vellum/utils/uuid.py,sha256=Ch6wWRgwICxLxJCTl5iE3EdRlZj2zADR-zUMUtjcMWM,214
1713
1716
  vellum/version.py,sha256=jq-1PlAYxN9AXuaZqbYk9ak27SgE2lw9Ia5gx1b1gVI,76
1714
1717
  vellum/workflows/README.md,sha256=hZdTKBIcsTKPofK68oPkBhyt0nnRh0csqC12k4FMHHA,3597
1715
- vellum/workflows/__init__.py,sha256=CssPsbNvN6rDhoLuqpEv7MMKGa51vE6dvAh6U31Pcio,71
1718
+ vellum/workflows/__init__.py,sha256=gd5AiZqVTcvqelhysG0jOWYfC6pJKRAVhS7qwf0bHU4,132
1716
1719
  vellum/workflows/constants.py,sha256=xweiPRUSVEnGz9BJvpIWu96Gfok89QneARu4K7wj7f8,1358
1717
1720
  vellum/workflows/context.py,sha256=ViyIeMDhUv-MhnynLaXPlvlbYxRU45ySvYidCNSbFZU,2458
1718
1721
  vellum/workflows/descriptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1728,7 +1731,7 @@ vellum/workflows/emitters/vellum_emitter.py,sha256=ECBIRA48WS5rIJd1iWUfye7B5Up7u
1728
1731
  vellum/workflows/environment/__init__.py,sha256=TJz0m9dwIs6YOwCTeuN0HHsU-ecyjc1OJXx4AFy83EQ,121
1729
1732
  vellum/workflows/environment/environment.py,sha256=Ck3RPKXJvtMGx_toqYQQQF-ZwXm5ijVwJpEPTeIJ4_Q,471
1730
1733
  vellum/workflows/errors/__init__.py,sha256=tWGPu5xyAU8gRb8_bl0fL7OfU3wxQ9UH6qVwy4X4P_Q,113
1731
- vellum/workflows/errors/types.py,sha256=nUWuniEfrhdtb-_2GzoDGlYnSJ_yuNUGjVkaKLNr-rM,4049
1734
+ vellum/workflows/errors/types.py,sha256=1LQzsEwCL-kqLGUxZcgJWahL-XNfIOwCz_5f_fWzLrM,4236
1732
1735
  vellum/workflows/events/__init__.py,sha256=V4mh766fyA70WvHelm9kfVZGrUgEKcJ9tJt8EepfQYU,832
1733
1736
  vellum/workflows/events/context.py,sha256=vCfMIPmz4j9Om36rRWa35A_JU_VccWWS52_mZkkqxak,3345
1734
1737
  vellum/workflows/events/node.py,sha256=yHVd-rX2E3qc2XLnZr0fW6uq4ZCMm34mnY2tzYceyOg,5884
@@ -1736,10 +1739,10 @@ vellum/workflows/events/relational_threads.py,sha256=zmLrBCBYpdpQV0snKH3HleST-_h
1736
1739
  vellum/workflows/events/stream.py,sha256=xhXJTZirFi0xad5neAQNogrIQ4h47fpnKbVC3vCM5Js,889
1737
1740
  vellum/workflows/events/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1738
1741
  vellum/workflows/events/tests/test_basic_workflow.py,sha256=Pj6orHsXz37jWC5FARi0Sx2Gjf99Owri2Cvr6Chb79k,1765
1739
- vellum/workflows/events/tests/test_event.py,sha256=V26TNmbo2aL4sDvcY3nPxCWgcoS4ejF-7VuesMeD04U,18451
1742
+ vellum/workflows/events/tests/test_event.py,sha256=RGVGz0DXMTvwCgdjua8rpPpCuCLDM5-8ET_3q4yH8_8,18493
1740
1743
  vellum/workflows/events/types.py,sha256=mVrqAH9Hs9SpXm08Hcxdyap_ImQPwGsxRr56rSNMP34,5043
1741
1744
  vellum/workflows/events/workflow.py,sha256=kLSWFXiDZH0TELWoDjQ_kHVomFnw8MVVUPDGIzgyosw,8997
1742
- vellum/workflows/exceptions.py,sha256=NiBiR3ggfmPxBVqD-H1SqmjI-7mIn0EStSN1BqApvCM,1213
1745
+ vellum/workflows/exceptions.py,sha256=Y7EULLN0kss8jxTLFNWEiOLMnyr1uKG83wiMvmtQ9Ak,1438
1743
1746
  vellum/workflows/executable.py,sha256=um-gLJMVYfGJwGJfZIPlCRHhHIYm6pn8PUEfeqrNx5k,218
1744
1747
  vellum/workflows/expressions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1745
1748
  vellum/workflows/expressions/accessor.py,sha256=3lu1-_-dBfZdJvtX-q66jbmRAZtqIfdsh_3_JNuzg1E,4462
@@ -1789,8 +1792,9 @@ vellum/workflows/graph/__init__.py,sha256=3sHlay5d_-uD7j3QJXiGl0WHFZZ_QScRvgyDhN
1789
1792
  vellum/workflows/graph/graph.py,sha256=vkpteMc2a61IFGHlrA50J4ntVj6m3agcyWrXGQEbjHc,11280
1790
1793
  vellum/workflows/graph/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1791
1794
  vellum/workflows/graph/tests/test_graph.py,sha256=0Pov0sCsxjzUDL9wy7xy9jFD-F2GsMJnZVEVFXzQGdM,15433
1792
- vellum/workflows/inputs/__init__.py,sha256=AbFEteIYEvCb14fM3EK7bhM-40-6s494rSlIhQ4Dsss,62
1795
+ vellum/workflows/inputs/__init__.py,sha256=02pj0IbJkN1AxTreswK39cNi45tA8GWcAAdRJve4cuM,116
1793
1796
  vellum/workflows/inputs/base.py,sha256=w3owT5B3rLBmIj-v-jL2l-HD4yd3hXK9RmHVd557BpA,5126
1797
+ vellum/workflows/inputs/dataset_row.py,sha256=T8lcn9qyC7IY0w3EIfnn4AwZ3pYw9sf4kdIi0VkX_Sw,1033
1794
1798
  vellum/workflows/inputs/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1795
1799
  vellum/workflows/inputs/tests/test_inputs.py,sha256=lioA8917mFLYq7Ml69UNkqUjcWbbxkxnpIEJ4FBaYBk,2206
1796
1800
  vellum/workflows/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1840,7 +1844,7 @@ vellum/workflows/nodes/displayable/bases/api_node/tests/test_node.py,sha256=5C59
1840
1844
  vellum/workflows/nodes/displayable/bases/base_prompt_node/__init__.py,sha256=Org3xTvgp1pA0uUXFfnJr29D3HzCey2lEdYF4zbIUgo,70
1841
1845
  vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py,sha256=ea20icDM1HB942wkH-XtXNSNCBDcjeOiN3vowkHL4fs,4477
1842
1846
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/__init__.py,sha256=Hl35IAoepRpE-j4cALaXVJIYTYOF3qszyVbxTj4kS1s,82
1843
- vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=TkVfwD5-GGWG32vtGMo4ZjuxWrjVYbK7tDWq0U9OBCM,17316
1847
+ vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py,sha256=eRhqxpkqcP5S4jx-vnnyHZvZAVQxKyCQ9kYxQCyWNvY,17921
1844
1848
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1845
1849
  vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py,sha256=xc53wGwVqxBnN7eoyWkJ-RJ-FeUpHKekkKjViASHAFg,27495
1846
1850
  vellum/workflows/nodes/displayable/bases/prompt_deployment_node.py,sha256=H9mM75EQpP6PUvsXCTbwjw4CqMMLf36m1G2XqiPEvH4,12139
@@ -1889,18 +1893,18 @@ vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py,sha256=ZB
1889
1893
  vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1890
1894
  vellum/workflows/nodes/displayable/subworkflow_deployment_node/tests/test_node.py,sha256=c98nMPogZ6iN_pTvVUMTB3J72Hj--H-XVgvvRXhdSQE,19085
1891
1895
  vellum/workflows/nodes/displayable/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1892
- vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py,sha256=MHuIolSsrY9ziwoXWsye3XOODncL9DLZOkNYzQMLhRw,4696
1896
+ vellum/workflows/nodes/displayable/tests/test_inline_text_prompt_node.py,sha256=E6PQ9OKcDlsJbWoxVKWgiAPgz9p59g1ONMgNggfOeiI,4868
1893
1897
  vellum/workflows/nodes/displayable/tests/test_search_node_error_handling.py,sha256=8aw8hDFL0ZXThvAa7yxrJN026EYGD4-Q1si3Phu9-_0,6307
1894
1898
  vellum/workflows/nodes/displayable/tests/test_search_node_wth_text_output.py,sha256=VepO5z1277c1y5N6LLIC31nnWD1aak2m5oPFplfJHHs,6935
1895
1899
  vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py,sha256=Bjv-wZyFgNaVZb9KEMMZd9lFoLzbPEPjEMpANizMZw4,2413
1896
1900
  vellum/workflows/nodes/displayable/tool_calling_node/__init__.py,sha256=3n0-ysmFKsr40CVxPthc0rfJgqVJeZuUEsCmYudLVRg,117
1897
- vellum/workflows/nodes/displayable/tool_calling_node/node.py,sha256=J4RNOggTx5nzovC0354SPGV-NkRpYnV51PMTYQ7aIQ8,8202
1901
+ vellum/workflows/nodes/displayable/tool_calling_node/node.py,sha256=Exw0_5-bzphKF42pKwHF-tH25s8MD6wSbGcp7jZuBFg,8236
1898
1902
  vellum/workflows/nodes/displayable/tool_calling_node/state.py,sha256=CcBVb_YtwfSSka4ze678k6-qwmzMSfjfVP8_Y95feSo,302
1899
1903
  vellum/workflows/nodes/displayable/tool_calling_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1900
1904
  vellum/workflows/nodes/displayable/tool_calling_node/tests/test_composio_service.py,sha256=in1fbEz5x1tx3uKv9YXdvOncsHucNL8Ro6Go7lBuuOQ,8962
1901
1905
  vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py,sha256=GZoeybB9uM7ai8sBLAtUMHrMVgh-WrJDWrKZci6feDs,11892
1902
1906
  vellum/workflows/nodes/displayable/tool_calling_node/tests/test_utils.py,sha256=SIu5GCj4tIE4fz-cAcdULtQfqZIhrcc3Doo6TWLXBws,8804
1903
- vellum/workflows/nodes/displayable/tool_calling_node/utils.py,sha256=c0fJA-de3yJKGTzKfjyZOkbVhIndSAhZqBZp_DpU1fg,24158
1907
+ vellum/workflows/nodes/displayable/tool_calling_node/utils.py,sha256=6XsvA77wF9MI6KBQNN1JMdpQwhK8pKUQtXgsPmq_I3Q,22837
1904
1908
  vellum/workflows/nodes/displayable/web_search_node/__init__.py,sha256=8FOnEP-n-U68cvxTlJW9wphIAGHq5aqjzLM-DoSSXnU,61
1905
1909
  vellum/workflows/nodes/displayable/web_search_node/node.py,sha256=NQYux2bOtuBF5E4tn-fXi5y3btURPRrNqMSM9MAZYI4,5091
1906
1910
  vellum/workflows/nodes/displayable/web_search_node/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1940,7 +1944,7 @@ vellum/workflows/resolvers/tests/test_resolver.py,sha256=jXkJBb9SwtoH__bBN-ECohp
1940
1944
  vellum/workflows/resolvers/types.py,sha256=Hndhlk69g6EKLh_LYg5ILepW5U_h_BYNllfzhS9k8p4,237
1941
1945
  vellum/workflows/runner/__init__.py,sha256=i1iG5sAhtpdsrlvwgH6B-m49JsINkiWyPWs8vyT-bqM,72
1942
1946
  vellum/workflows/runner/runner.py,sha256=lnVbqA1nSdWuyY1SZDpLDvnpLRQcQyWYOWrx3RIJpcg,41043
1943
- vellum/workflows/sandbox.py,sha256=jwlFFQjHDwmbVoBah_Q3i8K_BrzOt-F6TXFauiyVyIk,3021
1947
+ vellum/workflows/sandbox.py,sha256=mezSZmilR_fwR8164n8CEfzlMeQ55IqfapHp4ftImvQ,3212
1944
1948
  vellum/workflows/state/__init__.py,sha256=yUUdR-_Vl7UiixNDYQZ-GEM_kJI9dnOia75TtuNEsnE,60
1945
1949
  vellum/workflows/state/base.py,sha256=m9fCqbZn21GshCVCjJTD1dPZEQjFrsMXqlg7tM9fIwM,24283
1946
1950
  vellum/workflows/state/context.py,sha256=khM30U1iDNts5Xp8LXa_WfpkITNITexrDUUFJ5wZ2W4,8445
@@ -1950,12 +1954,13 @@ vellum/workflows/state/store.py,sha256=uVe-oN73KwGV6M6YLhwZMMUQhzTQomsVfVnb8V91g
1950
1954
  vellum/workflows/state/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1951
1955
  vellum/workflows/state/tests/test_state.py,sha256=zEVFIY2any41X2BA5Us_qqKpzH5HRqmyrUJ04GTO0pU,7484
1952
1956
  vellum/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1957
+ vellum/workflows/tests/test_dataset_row.py,sha256=qtz3cEcppCtr96co_8MmX4Jh1ro6bKZd_FGtRyFncRA,3370
1953
1958
  vellum/workflows/tests/test_sandbox.py,sha256=JKwaluI-lODQo7Ek9sjDstjL_WTdSqUlVik6ZVTfVOA,1826
1954
1959
  vellum/workflows/tests/test_undefined.py,sha256=zMCVliCXVNLrlC6hEGyOWDnQADJ2g83yc5FIM33zuo8,353
1955
1960
  vellum/workflows/types/__init__.py,sha256=KxUTMBGzuRCfiMqzzsykOeVvrrkaZmTTo1a7SLu8gRM,68
1956
1961
  vellum/workflows/types/code_execution_node_wrappers.py,sha256=fewX9bqF_4TZuK-gZYIn12s31-k03vHMGRpvFAPm11Y,3206
1957
1962
  vellum/workflows/types/core.py,sha256=TggDVs2lVya33xvu374EDhMC1b7RRlAAs0zWLaF46BA,1385
1958
- vellum/workflows/types/definition.py,sha256=2vq3uGT-m994zRcla0yTUsMiPLKSDuzEZs7H6U9QbiE,4993
1963
+ vellum/workflows/types/definition.py,sha256=727tDk-XzLAlpK2_OuPICz2VnFLW5WZd-WcZQrd2lvY,6854
1959
1964
  vellum/workflows/types/generics.py,sha256=8jptbEx1fnJV0Lhj0MpCJOT6yNiEWeTOYOwrEAb5CRU,1576
1960
1965
  vellum/workflows/types/stack.py,sha256=h7NE0vXR7l9DevFBIzIAk1Zh59K-kECQtDTKOUunwMY,1314
1961
1966
  vellum/workflows/types/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1963,7 +1968,7 @@ vellum/workflows/types/tests/test_definition.py,sha256=rvDYjdJ1rvAv0qHBN7i7s-_WA
1963
1968
  vellum/workflows/types/tests/test_utils.py,sha256=UnZog59tR577mVwqZRqqWn2fScoOU1H6up0EzS8zYhw,2536
1964
1969
  vellum/workflows/types/utils.py,sha256=mTctHITBybpt4855x32oCKALBEcMNLn-9cCmfEKgJHQ,6498
1965
1970
  vellum/workflows/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1966
- vellum/workflows/utils/functions.py,sha256=6WRRMb_XbxtvhUKOJq5ZChy0KKvlBaQCBiPhvecXT7I,10029
1971
+ vellum/workflows/utils/functions.py,sha256=z1V_HujCZI-pfOLIEwkd0_ZeeR1MNqq3fvgDke62NRo,11016
1967
1972
  vellum/workflows/utils/hmac.py,sha256=JJCczc6pyV6DuE1Oa0QVfYPUN_of3zEYmGFib3OZnrE,1135
1968
1973
  vellum/workflows/utils/names.py,sha256=QtHquoaGqRseu5gg2OcVGI2d_CMcEOvjb9KspwH4C-A,552
1969
1974
  vellum/workflows/utils/pydantic_schema.py,sha256=eR_bBtY-T0pttJP-ARwagSdCOnwPUtiT3cegm2lzDTQ,1310
@@ -1982,8 +1987,8 @@ vellum/workflows/workflows/event_filters.py,sha256=GSxIgwrX26a1Smfd-6yss2abGCnad
1982
1987
  vellum/workflows/workflows/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1983
1988
  vellum/workflows/workflows/tests/test_base_workflow.py,sha256=ptMntHzVyy8ZuzNgeTuk7hREgKQ5UBdgq8VJFSGaW4Y,20832
1984
1989
  vellum/workflows/workflows/tests/test_context.py,sha256=VJBUcyWVtMa_lE5KxdhgMu0WYNYnUQUDvTF7qm89hJ0,2333
1985
- vellum_ai-1.3.9.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1986
- vellum_ai-1.3.9.dist-info/METADATA,sha256=uOjA8lJ-F41325oLMigUN2TZ7A4Kuyi9d-fsQ6rRRB4,5547
1987
- vellum_ai-1.3.9.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1988
- vellum_ai-1.3.9.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1989
- vellum_ai-1.3.9.dist-info/RECORD,,
1990
+ vellum_ai-1.3.11.dist-info/LICENSE,sha256=hOypcdt481qGNISA784bnAGWAE6tyIf9gc2E78mYC3E,1574
1991
+ vellum_ai-1.3.11.dist-info/METADATA,sha256=OXKFjRVt9ymdiuFWO-WdvZ_lv_lWwiNYryNTEqoS054,5548
1992
+ vellum_ai-1.3.11.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
1993
+ vellum_ai-1.3.11.dist-info/entry_points.txt,sha256=HCH4yc_V3J_nDv3qJzZ_nYS8llCHZViCDP1ejgCc5Ak,42
1994
+ vellum_ai-1.3.11.dist-info/RECORD,,
@@ -114,7 +114,7 @@ def test_serialize_workflow():
114
114
  "block_type": "VARIABLE",
115
115
  "state": None,
116
116
  "cache_config": None,
117
- "input_variable": "question",
117
+ "input_variable": "8eb8b551-9b48-43b3-861f-52adb5c585a8",
118
118
  }
119
119
  ],
120
120
  }
@@ -115,7 +115,7 @@ def test_serialize_workflow():
115
115
  "block_type": "VARIABLE",
116
116
  "state": None,
117
117
  "cache_config": None,
118
- "input_variable": "question",
118
+ "input_variable": "8eb8b551-9b48-43b3-861f-52adb5c585a8",
119
119
  }
120
120
  ],
121
121
  }
@@ -51,7 +51,6 @@ from vellum.workflows.references.state_value import StateValueReference
51
51
  from vellum.workflows.references.vellum_secret import VellumSecretReference
52
52
  from vellum.workflows.references.workflow_input import WorkflowInputReference
53
53
  from vellum.workflows.types.core import JsonArray, JsonObject
54
- from vellum.workflows.types.definition import DeploymentDefinition
55
54
  from vellum.workflows.types.generics import is_workflow_class
56
55
  from vellum.workflows.utils.functions import compile_function_definition
57
56
  from vellum.workflows.utils.uuids import uuid4_from_hash
@@ -425,29 +424,9 @@ def serialize_value(executable_id: UUID, display_context: "WorkflowDisplayContex
425
424
  },
426
425
  }
427
426
 
428
- if isinstance(value, DeploymentDefinition):
429
- workflow_deployment_release = display_context.client.workflow_deployments.retrieve_workflow_deployment_release(
430
- value.deployment, value.release_tag
431
- )
432
- name = workflow_deployment_release.deployment.name or value.deployment
433
- description = workflow_deployment_release.description or f"Workflow Deployment for {name}"
434
-
435
- return {
436
- "type": "CONSTANT_VALUE",
437
- "value": {
438
- "type": "JSON",
439
- "value": {
440
- "type": "WORKFLOW_DEPLOYMENT",
441
- "name": name,
442
- "description": description,
443
- "deployment": value.deployment,
444
- "release_tag": value.release_tag,
445
- },
446
- },
447
- }
448
-
449
427
  if isinstance(value, BaseModel):
450
- dict_value = value.model_dump()
428
+ context = {"executable_id": executable_id, "client": display_context.client}
429
+ dict_value = value.model_dump(context=context)
451
430
  return serialize_value(executable_id, display_context, dict_value)
452
431
 
453
432
  if callable(value):