vellum-ai 1.2.0__py3-none-any.whl → 1.2.2__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 (94) hide show
  1. vellum/__init__.py +18 -1
  2. vellum/client/__init__.py +3 -0
  3. vellum/client/core/client_wrapper.py +2 -2
  4. vellum/client/errors/__init__.py +10 -1
  5. vellum/client/errors/too_many_requests_error.py +11 -0
  6. vellum/client/errors/unauthorized_error.py +11 -0
  7. vellum/client/reference.md +94 -0
  8. vellum/client/resources/__init__.py +2 -0
  9. vellum/client/resources/events/__init__.py +4 -0
  10. vellum/client/resources/events/client.py +165 -0
  11. vellum/client/resources/events/raw_client.py +207 -0
  12. vellum/client/types/__init__.py +6 -0
  13. vellum/client/types/error_detail_response.py +22 -0
  14. vellum/client/types/event_create_response.py +26 -0
  15. vellum/client/types/execution_thinking_vellum_value.py +1 -1
  16. vellum/client/types/thinking_vellum_value.py +1 -1
  17. vellum/client/types/thinking_vellum_value_request.py +1 -1
  18. vellum/client/types/workflow_event.py +33 -0
  19. vellum/errors/too_many_requests_error.py +3 -0
  20. vellum/errors/unauthorized_error.py +3 -0
  21. vellum/prompts/blocks/compilation.py +13 -11
  22. vellum/resources/events/__init__.py +3 -0
  23. vellum/resources/events/client.py +3 -0
  24. vellum/resources/events/raw_client.py +3 -0
  25. vellum/types/error_detail_response.py +3 -0
  26. vellum/types/event_create_response.py +3 -0
  27. vellum/types/workflow_event.py +3 -0
  28. vellum/workflows/emitters/vellum_emitter.py +16 -69
  29. vellum/workflows/events/tests/test_event.py +1 -0
  30. vellum/workflows/events/workflow.py +3 -0
  31. vellum/workflows/nodes/bases/base.py +0 -1
  32. vellum/workflows/nodes/core/inline_subworkflow_node/tests/test_node.py +35 -0
  33. vellum/workflows/nodes/displayable/bases/api_node/node.py +4 -0
  34. vellum/workflows/nodes/displayable/bases/api_node/tests/test_node.py +26 -0
  35. vellum/workflows/nodes/displayable/bases/inline_prompt_node/node.py +6 -1
  36. vellum/workflows/nodes/displayable/bases/inline_prompt_node/tests/test_inline_prompt_node.py +22 -0
  37. vellum/workflows/nodes/displayable/bases/utils.py +4 -2
  38. vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +88 -2
  39. vellum/workflows/nodes/displayable/tool_calling_node/node.py +1 -0
  40. vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py +85 -1
  41. vellum/workflows/nodes/displayable/tool_calling_node/tests/test_utils.py +12 -0
  42. vellum/workflows/nodes/displayable/tool_calling_node/utils.py +5 -2
  43. vellum/workflows/ports/port.py +1 -11
  44. vellum/workflows/sandbox.py +6 -3
  45. vellum/workflows/state/context.py +14 -0
  46. vellum/workflows/state/encoder.py +19 -1
  47. vellum/workflows/types/definition.py +4 -4
  48. vellum/workflows/utils/hmac.py +44 -0
  49. vellum/workflows/utils/vellum_variables.py +5 -3
  50. vellum/workflows/workflows/base.py +1 -0
  51. {vellum_ai-1.2.0.dist-info → vellum_ai-1.2.2.dist-info}/METADATA +1 -1
  52. {vellum_ai-1.2.0.dist-info → vellum_ai-1.2.2.dist-info}/RECORD +94 -76
  53. vellum_ee/workflows/display/nodes/base_node_display.py +19 -10
  54. vellum_ee/workflows/display/nodes/vellum/api_node.py +1 -4
  55. vellum_ee/workflows/display/nodes/vellum/code_execution_node.py +1 -4
  56. vellum_ee/workflows/display/nodes/vellum/conditional_node.py +1 -4
  57. vellum_ee/workflows/display/nodes/vellum/error_node.py +6 -4
  58. vellum_ee/workflows/display/nodes/vellum/final_output_node.py +6 -4
  59. vellum_ee/workflows/display/nodes/vellum/guardrail_node.py +1 -4
  60. vellum_ee/workflows/display/nodes/vellum/inline_prompt_node.py +34 -15
  61. vellum_ee/workflows/display/nodes/vellum/inline_subworkflow_node.py +1 -4
  62. vellum_ee/workflows/display/nodes/vellum/map_node.py +1 -4
  63. vellum_ee/workflows/display/nodes/vellum/merge_node.py +1 -4
  64. vellum_ee/workflows/display/nodes/vellum/note_node.py +2 -4
  65. vellum_ee/workflows/display/nodes/vellum/prompt_deployment_node.py +1 -4
  66. vellum_ee/workflows/display/nodes/vellum/search_node.py +1 -4
  67. vellum_ee/workflows/display/nodes/vellum/subworkflow_deployment_node.py +1 -4
  68. vellum_ee/workflows/display/nodes/vellum/templating_node.py +1 -4
  69. vellum_ee/workflows/display/nodes/vellum/tests/test_code_execution_node.py +1 -0
  70. vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py +239 -1
  71. vellum_ee/workflows/display/tests/test_base_workflow_display.py +53 -1
  72. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_api_node_serialization.py +4 -0
  73. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_code_execution_node_serialization.py +12 -0
  74. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +16 -0
  75. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_error_node_serialization.py +5 -0
  76. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_guardrail_node_serialization.py +4 -0
  77. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_inline_subworkflow_serialization.py +4 -0
  78. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_map_node_serialization.py +4 -0
  79. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_merge_node_serialization.py +4 -0
  80. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_prompt_deployment_serialization.py +12 -0
  81. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_search_node_serialization.py +4 -0
  82. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_subworkflow_deployment_serialization.py +4 -0
  83. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_templating_node_serialization.py +4 -0
  84. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_terminal_node_serialization.py +5 -0
  85. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_composio_serialization.py +1 -0
  86. vellum_ee/workflows/display/tests/workflow_serialization/test_complex_terminal_node_serialization.py +5 -0
  87. vellum_ee/workflows/display/utils/expressions.py +4 -0
  88. vellum_ee/workflows/display/utils/registry.py +46 -0
  89. vellum_ee/workflows/display/workflows/base_workflow_display.py +1 -1
  90. vellum_ee/workflows/tests/test_registry.py +169 -0
  91. vellum_ee/workflows/tests/test_server.py +72 -0
  92. {vellum_ai-1.2.0.dist-info → vellum_ai-1.2.2.dist-info}/LICENSE +0 -0
  93. {vellum_ai-1.2.0.dist-info → vellum_ai-1.2.2.dist-info}/WHEEL +0 -0
  94. {vellum_ai-1.2.0.dist-info → vellum_ai-1.2.2.dist-info}/entry_points.txt +0 -0
@@ -1,12 +1,14 @@
1
1
  import json
2
2
  from uuid import uuid4
3
- from typing import Any, Iterator
3
+ from typing import Any, Iterator, List
4
4
 
5
5
  from vellum import ChatMessage
6
+ from vellum.client.types.execute_prompt_event import ExecutePromptEvent
6
7
  from vellum.client.types.fulfilled_execute_prompt_event import FulfilledExecutePromptEvent
7
8
  from vellum.client.types.function_call import FunctionCall
8
9
  from vellum.client.types.function_call_vellum_value import FunctionCallVellumValue
9
10
  from vellum.client.types.initiated_execute_prompt_event import InitiatedExecutePromptEvent
11
+ from vellum.client.types.prompt_output import PromptOutput
10
12
  from vellum.client.types.string_chat_message_content import StringChatMessageContent
11
13
  from vellum.client.types.string_vellum_value import StringVellumValue
12
14
  from vellum.client.types.variable_prompt_block import VariablePromptBlock
@@ -25,6 +27,7 @@ from vellum.workflows.outputs.base import BaseOutputs
25
27
  from vellum.workflows.state.base import BaseState, StateMeta
26
28
  from vellum.workflows.state.context import WorkflowContext
27
29
  from vellum.workflows.types.definition import DeploymentDefinition
30
+ from vellum.workflows.workflows.event_filters import all_workflow_event_filter
28
31
 
29
32
 
30
33
  def first_function() -> str:
@@ -238,3 +241,84 @@ def test_tool_calling_node_with_generic_type_parameter():
238
241
  assert node is not None
239
242
  assert isinstance(node, TestToolCallingNode)
240
243
  assert node.state == state
244
+
245
+
246
+ def test_tool_calling_node_workflow_is_dynamic(vellum_adhoc_prompt_client):
247
+ """
248
+ Test workflow_version_exec_config without any mocks to see if that's the issue.
249
+ """
250
+
251
+ def generate_prompt_events(*args, **kwargs) -> Iterator[ExecutePromptEvent]:
252
+ execution_id = str(uuid4())
253
+
254
+ call_count = vellum_adhoc_prompt_client.adhoc_execute_prompt_stream.call_count
255
+ expected_outputs: List[PromptOutput]
256
+ if call_count == 1:
257
+ expected_outputs = [
258
+ FunctionCallVellumValue(
259
+ value=FunctionCall(
260
+ arguments={"var_1": 1, "var_2": 2},
261
+ id="call_123",
262
+ name="add_numbers_workflow",
263
+ state="FULFILLED",
264
+ ),
265
+ ),
266
+ ]
267
+ else:
268
+ expected_outputs = [StringVellumValue(value="The result is 3")]
269
+
270
+ events: List[ExecutePromptEvent] = [
271
+ InitiatedExecutePromptEvent(execution_id=execution_id),
272
+ FulfilledExecutePromptEvent(
273
+ execution_id=execution_id,
274
+ outputs=expected_outputs,
275
+ ),
276
+ ]
277
+ yield from events
278
+
279
+ vellum_adhoc_prompt_client.adhoc_execute_prompt_stream.side_effect = generate_prompt_events
280
+
281
+ class AddNode(BaseNode):
282
+
283
+ class Outputs(BaseNode.Outputs):
284
+ result: int
285
+
286
+ def run(self) -> Outputs:
287
+ return self.Outputs(result=1)
288
+
289
+ class AddNumbersWorkflow(BaseWorkflow[BaseInputs, BaseState]):
290
+ """
291
+ A simple workflow that adds two numbers.
292
+ """
293
+
294
+ graph = AddNode
295
+
296
+ class Outputs(BaseWorkflow.Outputs):
297
+ result = AddNode.Outputs.result
298
+
299
+ class TestToolCallingNode(ToolCallingNode):
300
+ ml_model = "gpt-4o-mini"
301
+ blocks = []
302
+ functions = [AddNumbersWorkflow]
303
+ prompt_inputs = {}
304
+
305
+ # GIVEN a workflow with just a tool calling node
306
+ class ToolCallingWorkflow(BaseWorkflow[BaseInputs, BaseState]):
307
+ graph = TestToolCallingNode
308
+
309
+ class Outputs(BaseWorkflow.Outputs):
310
+ text: str = TestToolCallingNode.Outputs.text
311
+ chat_history: List[ChatMessage] = TestToolCallingNode.Outputs.chat_history
312
+
313
+ workflow = ToolCallingWorkflow()
314
+
315
+ # WHEN the workflow is executed and we capture all events
316
+ events = list(workflow.stream(event_filter=all_workflow_event_filter))
317
+
318
+ # AND we should find workflow execution initiated events
319
+ initiated_events = [event for event in events if event.name == "workflow.execution.initiated"]
320
+ assert len(initiated_events) == 3 # Main workflow + tool calling internal + inline workflow
321
+
322
+ assert initiated_events[0].body.workflow_definition.is_dynamic is False # Main workflow
323
+ assert initiated_events[1].body.workflow_definition.is_dynamic is True # Tool calling internal
324
+ assert initiated_events[2].body.workflow_definition.is_dynamic is True # Inline workflow
@@ -238,3 +238,15 @@ def test_create_tool_prompt_node_chat_history_block_dict(vellum_adhoc_prompt_cli
238
238
  ),
239
239
  VariablePromptBlock(block_type="VARIABLE", state=None, cache_config=None, input_variable="chat_history"),
240
240
  ]
241
+
242
+
243
+ def test_get_mcp_tool_name_snake_case():
244
+ """Test MCPToolDefinition function name generation with snake case."""
245
+ mcp_tool = MCPToolDefinition(
246
+ name="create_repository",
247
+ server=MCPServer(name="Github Server", url="https://api.github.com"),
248
+ parameters={"repository_name": "string", "description": "string"},
249
+ )
250
+
251
+ result = get_mcp_tool_name(mcp_tool)
252
+ assert result == "github_server__create_repository"
@@ -505,6 +505,7 @@ def create_function_node(
505
505
  )
506
506
  return node
507
507
  elif is_workflow_class(function):
508
+ function.is_dynamic = True
508
509
  node = type(
509
510
  f"DynamicInlineSubworkflowNode_{function.__name__}",
510
511
  (DynamicInlineSubworkflowNode,),
@@ -574,10 +575,12 @@ def get_function_name(function: ToolBase) -> str:
574
575
  name = str(function.deployment_id or function.deployment_name)
575
576
  return name.replace("-", "")
576
577
  elif isinstance(function, ComposioToolDefinition):
577
- return function.name
578
+ # model post init sets the name to the action if it's not set
579
+ return function.name # type: ignore[return-value]
578
580
  else:
579
581
  return snake_case(function.__name__)
580
582
 
581
583
 
582
584
  def get_mcp_tool_name(tool_def: MCPToolDefinition) -> str:
583
- return f"{tool_def.server.name}__{tool_def.name}"
585
+ server_name = snake_case(tool_def.server.name)
586
+ return f"{server_name}__{tool_def.name}"
@@ -7,7 +7,7 @@ from vellum.workflows.descriptors.base import BaseDescriptor
7
7
  from vellum.workflows.descriptors.exceptions import InvalidExpressionException
8
8
  from vellum.workflows.edges.edge import Edge
9
9
  from vellum.workflows.errors.types import WorkflowErrorCode
10
- from vellum.workflows.exceptions import NodeException, WorkflowInitializationException
10
+ from vellum.workflows.exceptions import NodeException
11
11
  from vellum.workflows.graph import Graph, GraphTarget
12
12
  from vellum.workflows.state.base import BaseState
13
13
  from vellum.workflows.types.core import ConditionType
@@ -107,13 +107,3 @@ class Port:
107
107
  cls, source_type: Type[Any], handler: GetCoreSchemaHandler
108
108
  ) -> core_schema.CoreSchema:
109
109
  return core_schema.is_instance_schema(cls)
110
-
111
- def validate(self):
112
- if (
113
- not self.default
114
- and self._condition_type in (ConditionType.IF, ConditionType.ELIF)
115
- and self._condition is None
116
- ):
117
- raise WorkflowInitializationException(
118
- f"Class {self.node_class.__name__}'s {self.name} should have a defined condition and cannot be empty."
119
- )
@@ -16,6 +16,9 @@ class WorkflowSandboxRunner(Generic[WorkflowType]):
16
16
  inputs: Optional[Sequence[BaseInputs]] = None, # DEPRECATED - remove in v2.0.0
17
17
  dataset: Optional[Sequence[BaseInputs]] = None,
18
18
  ):
19
+ dotenv.load_dotenv()
20
+ self._logger = load_logger()
21
+
19
22
  if dataset is not None and inputs is not None:
20
23
  raise ValueError(
21
24
  "Cannot specify both 'dataset' and 'inputs' parameters. " "Use 'dataset' as 'inputs' is deprecated."
@@ -24,6 +27,9 @@ class WorkflowSandboxRunner(Generic[WorkflowType]):
24
27
  if dataset is not None:
25
28
  actual_inputs = dataset
26
29
  elif inputs is not None:
30
+ self._logger.warning(
31
+ "The 'inputs' parameter is deprecated and will be removed in v2.0.0. " "Please use 'dataset' instead."
32
+ )
27
33
  actual_inputs = inputs
28
34
  else:
29
35
  raise ValueError("Either 'dataset' or 'inputs' parameter is required")
@@ -34,9 +40,6 @@ class WorkflowSandboxRunner(Generic[WorkflowType]):
34
40
  self._workflow = workflow
35
41
  self._inputs = actual_inputs
36
42
 
37
- dotenv.load_dotenv()
38
- self._logger = load_logger()
39
-
40
43
  def run(self, index: int = 0):
41
44
  if index < 0:
42
45
  self._logger.warning("Index is less than 0, running first input")
@@ -13,6 +13,7 @@ from vellum.workflows.vellum_client import create_vellum_client
13
13
 
14
14
  if TYPE_CHECKING:
15
15
  from vellum.workflows.events.workflow import WorkflowEvent
16
+ from vellum.workflows.workflows.base import BaseWorkflow
16
17
 
17
18
 
18
19
  class WorkflowContext:
@@ -131,6 +132,19 @@ class WorkflowContext:
131
132
  def _get_all_node_output_mocks(self) -> List[MockNodeExecution]:
132
133
  return [mock for mocks in self._node_output_mocks_map.values() for mock in mocks]
133
134
 
135
+ def resolve_workflow_deployment(self, deployment_name: str, release_tag: str) -> Optional["BaseWorkflow"]:
136
+ """
137
+ Resolve a workflow deployment by name and release tag.
138
+
139
+ Args:
140
+ deployment_name: The name of the workflow deployment
141
+ release_tag: The release tag to resolve
142
+
143
+ Returns:
144
+ BaseWorkflow instance if found, None otherwise
145
+ """
146
+ return None
147
+
134
148
  @classmethod
135
149
  def create_from(cls, context):
136
150
  return cls(vellum_client=context.vellum_client, generated_files=context.generated_files)
@@ -2,8 +2,10 @@ from dataclasses import asdict, is_dataclass
2
2
  from datetime import datetime
3
3
  import enum
4
4
  import inspect
5
+ from io import StringIO
5
6
  from json import JSONEncoder
6
7
  from queue import Queue
8
+ import sys
7
9
  from uuid import UUID
8
10
  from typing import Any, Callable, Dict, Type
9
11
 
@@ -18,6 +20,22 @@ from vellum.workflows.state.base import BaseState, NodeExecutionCache
18
20
  from vellum.workflows.utils.functions import compile_function_definition
19
21
 
20
22
 
23
+ def virtual_open(file_path: str, mode: str = "r"):
24
+ """
25
+ Open a file, checking VirtualFileFinder instances first before falling back to regular open().
26
+ """
27
+ for finder in sys.meta_path:
28
+ if hasattr(finder, "loader") and hasattr(finder.loader, "_get_code"):
29
+ namespace = finder.loader.namespace
30
+ if file_path.startswith(namespace + "/"):
31
+ relative_path = file_path[len(namespace) + 1 :]
32
+ content = finder.loader._get_code(relative_path)
33
+ if content is not None:
34
+ return StringIO(content)
35
+
36
+ return open(file_path, mode)
37
+
38
+
21
39
  class DefaultStateEncoder(JSONEncoder):
22
40
  encoders: Dict[Type, Callable] = {}
23
41
 
@@ -66,7 +84,7 @@ class DefaultStateEncoder(JSONEncoder):
66
84
  function_definition = compile_function_definition(obj)
67
85
  source_path = inspect.getsourcefile(obj)
68
86
  if source_path is not None:
69
- with open(source_path) as f:
87
+ with virtual_open(source_path) as f:
70
88
  source_code = f.read()
71
89
  else:
72
90
  source_code = f"# Error: Source code not available for {obj.__name__}"
@@ -111,11 +111,11 @@ class ComposioToolDefinition(UniversalBaseModel):
111
111
  action: str # Specific action like "GITHUB_CREATE_AN_ISSUE"
112
112
  description: str
113
113
  user_id: Optional[str] = None
114
+ name: str = ""
114
115
 
115
- @property
116
- def name(self) -> str:
117
- """Generate a function name for this tool"""
118
- return self.action.lower()
116
+ def model_post_init(self, __context: Any):
117
+ if self.name == "":
118
+ self.name = self.action.lower()
119
119
 
120
120
 
121
121
  class MCPServer(UniversalBaseModel):
@@ -0,0 +1,44 @@
1
+ import hashlib
2
+ import hmac
3
+ import os
4
+ import time
5
+
6
+ from requests import PreparedRequest
7
+
8
+
9
+ def _sign_request(request: PreparedRequest, secret: str) -> None:
10
+ """
11
+ Sign a request with HMAC using the same pattern as Django implementation.
12
+
13
+ Args:
14
+ request: The prepared request to sign
15
+ secret: The HMAC secret string
16
+ """
17
+ timestamp = str(int(time.time()))
18
+
19
+ body = request.body or b""
20
+ if isinstance(body, str):
21
+ body = body.encode()
22
+
23
+ message = f"{timestamp}\n{request.method}\n{request.url}\n".encode() + body
24
+
25
+ signature = hmac.new(secret.encode("utf-8"), message, hashlib.sha256).hexdigest()
26
+
27
+ hmac_headers = {
28
+ "X-Vellum-Timestamp": timestamp,
29
+ "X-Vellum-Signature": signature,
30
+ }
31
+
32
+ request.headers.update(hmac_headers)
33
+
34
+
35
+ def sign_request_with_env_secret(request: PreparedRequest) -> None:
36
+ """
37
+ Sign a request using VELLUM_HMAC_SECRET environment variable if available.
38
+
39
+ Args:
40
+ request: The prepared request to sign
41
+ """
42
+ hmac_secret = os.environ.get("VELLUM_HMAC_SECRET")
43
+ if hmac_secret:
44
+ _sign_request(request, hmac_secret)
@@ -1,7 +1,7 @@
1
1
  import typing
2
2
  from typing import List, Tuple, Type, Union, get_args, get_origin
3
3
 
4
- from vellum import ( # VellumVideo,; VellumVideoRequest,
4
+ from vellum import (
5
5
  ChatMessage,
6
6
  ChatMessageRequest,
7
7
  FunctionCall,
@@ -19,6 +19,8 @@ from vellum import ( # VellumVideo,; VellumVideoRequest,
19
19
  VellumValue,
20
20
  VellumValueRequest,
21
21
  VellumVariableType,
22
+ VellumVideo,
23
+ VellumVideoRequest,
22
24
  )
23
25
  from vellum.workflows.descriptors.base import BaseDescriptor
24
26
  from vellum.workflows.types.core import Json
@@ -67,8 +69,8 @@ def primitive_type_to_vellum_variable_type(type_: Union[Type, BaseDescriptor]) -
67
69
  return "FUNCTION_CALL"
68
70
  elif _is_type_optionally_in(type_, (VellumAudio, VellumAudioRequest)):
69
71
  return "AUDIO"
70
- # elif _is_type_optionally_in(type_, (VellumVideo, VellumVideoRequest)):
71
- # return "VIDEO"
72
+ elif _is_type_optionally_in(type_, (VellumVideo, VellumVideoRequest)):
73
+ return "VIDEO"
72
74
  elif _is_type_optionally_in(type_, (VellumImage, VellumImageRequest)):
73
75
  return "IMAGE"
74
76
  elif _is_type_optionally_in(type_, (VellumDocument, VellumDocumentRequest)):
@@ -211,6 +211,7 @@ class BaseWorkflow(Generic[InputsType, StateType], metaclass=_BaseWorkflowMeta):
211
211
  unused_graphs: ClassVar[Set[GraphAttribute]] # nodes or graphs that are defined but not used in the graph
212
212
  emitters: List[BaseWorkflowEmitter]
213
213
  resolvers: List[BaseWorkflowResolver]
214
+ is_dynamic: ClassVar[bool] = False
214
215
 
215
216
  class Outputs(BaseOutputs):
216
217
  pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 1.2.0
3
+ Version: 1.2.2
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0