vellum-ai 1.0.10__py3-none-any.whl → 1.1.0__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 (76) hide show
  1. vellum/__init__.py +2 -2
  2. vellum/client/__init__.py +0 -4
  3. vellum/client/core/client_wrapper.py +2 -2
  4. vellum/client/reference.md +2 -3
  5. vellum/client/resources/__init__.py +0 -2
  6. vellum/client/resources/workflow_deployments/client.py +119 -0
  7. vellum/client/types/__init__.py +2 -0
  8. vellum/client/types/api_request_parent_context.py +1 -0
  9. vellum/client/types/external_parent_context.py +36 -0
  10. vellum/client/types/node_execution_fulfilled_event.py +1 -0
  11. vellum/client/types/node_execution_initiated_event.py +1 -0
  12. vellum/client/types/node_execution_paused_event.py +1 -0
  13. vellum/client/types/node_execution_rejected_event.py +1 -0
  14. vellum/client/types/node_execution_resumed_event.py +1 -0
  15. vellum/client/types/node_execution_span.py +1 -0
  16. vellum/client/types/node_execution_span_attributes.py +1 -0
  17. vellum/client/types/node_execution_streaming_event.py +1 -0
  18. vellum/client/types/node_parent_context.py +1 -0
  19. vellum/client/types/parent_context.py +2 -0
  20. vellum/client/types/prompt_deployment_parent_context.py +1 -0
  21. vellum/client/types/slim_workflow_execution_read.py +1 -0
  22. vellum/client/types/span_link.py +1 -0
  23. vellum/client/types/workflow_deployment_event_executions_response.py +1 -0
  24. vellum/client/types/workflow_deployment_parent_context.py +1 -0
  25. vellum/client/types/workflow_event_execution_read.py +1 -0
  26. vellum/client/types/workflow_execution_detail.py +1 -0
  27. vellum/client/types/workflow_execution_fulfilled_event.py +1 -0
  28. vellum/client/types/workflow_execution_initiated_event.py +1 -0
  29. vellum/client/types/workflow_execution_paused_event.py +1 -0
  30. vellum/client/types/workflow_execution_rejected_event.py +1 -0
  31. vellum/client/types/workflow_execution_resumed_event.py +1 -0
  32. vellum/client/types/workflow_execution_snapshotted_event.py +1 -0
  33. vellum/client/types/workflow_execution_span.py +1 -0
  34. vellum/client/types/workflow_execution_span_attributes.py +1 -0
  35. vellum/client/types/workflow_execution_streaming_event.py +1 -0
  36. vellum/client/types/workflow_parent_context.py +1 -0
  37. vellum/client/types/workflow_sandbox_parent_context.py +1 -0
  38. vellum/{resources/release_reviews/__init__.py → types/external_parent_context.py} +1 -1
  39. vellum/workflows/descriptors/base.py +31 -1
  40. vellum/workflows/descriptors/utils.py +19 -1
  41. vellum/workflows/emitters/vellum_emitter.py +3 -2
  42. vellum/workflows/events/types.py +6 -0
  43. vellum/workflows/expressions/accessor.py +23 -15
  44. vellum/workflows/expressions/add.py +41 -0
  45. vellum/workflows/expressions/length.py +35 -0
  46. vellum/workflows/expressions/minus.py +41 -0
  47. vellum/workflows/expressions/tests/test_add.py +72 -0
  48. vellum/workflows/expressions/tests/test_length.py +38 -0
  49. vellum/workflows/expressions/tests/test_minus.py +72 -0
  50. vellum/workflows/integrations/composio_service.py +4 -0
  51. vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +1 -1
  52. vellum/workflows/nodes/displayable/inline_prompt_node/node.py +2 -2
  53. vellum/workflows/nodes/displayable/tests/test_text_prompt_deployment_node.py +5 -15
  54. vellum/workflows/nodes/displayable/tool_calling_node/node.py +12 -1
  55. vellum/workflows/nodes/displayable/tool_calling_node/state.py +2 -0
  56. vellum/workflows/nodes/displayable/tool_calling_node/tests/test_composio_service.py +49 -0
  57. vellum/workflows/nodes/displayable/tool_calling_node/tests/test_node.py +3 -8
  58. vellum/workflows/nodes/displayable/tool_calling_node/utils.py +167 -50
  59. vellum/workflows/state/context.py +13 -2
  60. vellum/workflows/types/definition.py +3 -8
  61. vellum/workflows/types/tests/test_definition.py +3 -4
  62. vellum/workflows/utils/functions.py +1 -1
  63. vellum/workflows/utils/tests/test_functions.py +3 -3
  64. {vellum_ai-1.0.10.dist-info → vellum_ai-1.1.0.dist-info}/METADATA +1 -1
  65. {vellum_ai-1.0.10.dist-info → vellum_ai-1.1.0.dist-info}/RECORD +73 -68
  66. vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py +93 -0
  67. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_composio_serialization.py +0 -4
  68. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_mcp_serialization.py +98 -0
  69. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_workflow_deployment_serialization.py +1 -1
  70. vellum_ee/workflows/display/utils/expressions.py +13 -1
  71. vellum/client/resources/release_reviews/__init__.py +0 -2
  72. vellum/client/resources/release_reviews/client.py +0 -139
  73. vellum/resources/release_reviews/client.py +0 -3
  74. {vellum_ai-1.0.10.dist-info → vellum_ai-1.1.0.dist-info}/LICENSE +0 -0
  75. {vellum_ai-1.0.10.dist-info → vellum_ai-1.1.0.dist-info}/WHEEL +0 -0
  76. {vellum_ai-1.0.10.dist-info → vellum_ai-1.1.0.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  import json
2
2
  from uuid import uuid4
3
- from typing import Any, Iterator, List
3
+ from typing import Any, Iterator
4
4
 
5
5
  from vellum import ChatMessage
6
6
  from vellum.client.types.fulfilled_execute_prompt_event import FulfilledExecutePromptEvent
@@ -15,6 +15,7 @@ from vellum.workflows import BaseWorkflow
15
15
  from vellum.workflows.inputs.base import BaseInputs
16
16
  from vellum.workflows.nodes.bases import BaseNode
17
17
  from vellum.workflows.nodes.displayable.tool_calling_node.node import ToolCallingNode
18
+ from vellum.workflows.nodes.displayable.tool_calling_node.state import ToolCallingState
18
19
  from vellum.workflows.nodes.displayable.tool_calling_node.utils import create_function_node, create_tool_router_node
19
20
  from vellum.workflows.outputs.base import BaseOutputs
20
21
  from vellum.workflows.state.base import BaseState, StateMeta
@@ -44,7 +45,7 @@ def test_port_condition_match_function_name():
44
45
  )
45
46
 
46
47
  # AND a state with a function call to the first function
47
- state = BaseState(
48
+ state = ToolCallingState(
48
49
  meta=StateMeta(
49
50
  node_outputs={
50
51
  router_node.Outputs.results: [
@@ -116,12 +117,6 @@ def test_tool_calling_node_inline_workflow_context():
116
117
  )
117
118
  function_node._context = parent_context
118
119
 
119
- # Create a state with chat_history for the function node
120
- class TestState(BaseState):
121
- chat_history: List[ChatMessage] = []
122
-
123
- function_node.state = TestState(meta=StateMeta(node_outputs={tool_router_node.Outputs.text: '{"arguments": {}}'}))
124
-
125
120
  # WHEN the function node runs
126
121
  outputs = list(function_node.run())
127
122
 
@@ -5,6 +5,8 @@ from typing import Any, Callable, Dict, Iterator, List, Optional, Type, Union, c
5
5
  from pydash import snake_case
6
6
 
7
7
  from vellum import ChatMessage, PromptBlock
8
+ from vellum.client.types.array_chat_message_content import ArrayChatMessageContent
9
+ from vellum.client.types.array_chat_message_content_item import ArrayChatMessageContentItem
8
10
  from vellum.client.types.function_call_chat_message_content import FunctionCallChatMessageContent
9
11
  from vellum.client.types.function_call_chat_message_content_value import FunctionCallChatMessageContentValue
10
12
  from vellum.client.types.function_definition import FunctionDefinition
@@ -59,6 +61,9 @@ class FunctionCallNodeMixin:
59
61
  content=StringChatMessageContent(value=json.dumps(result, cls=DefaultStateEncoder)),
60
62
  )
61
63
  )
64
+ with state.__quiet__():
65
+ state.current_function_calls_processed += 1
66
+ state.current_prompt_output_index += 1
62
67
 
63
68
 
64
69
  class ToolRouterNode(InlinePromptNode[ToolCallingState]):
@@ -73,32 +78,52 @@ class ToolRouterNode(InlinePromptNode[ToolCallingState]):
73
78
  raise NodeException(message=max_iterations_message, code=WorkflowErrorCode.NODE_EXECUTION)
74
79
 
75
80
  generator = super().run()
81
+ with self.state.__quiet__():
82
+ self.state.current_prompt_output_index = 0
83
+ self.state.current_function_calls_processed = 0
84
+ self.state.prompt_iterations += 1
76
85
  for output in generator:
77
- if output.name == "results" and output.value:
78
- values = cast(List[Any], output.value)
79
- if values and len(values) > 0:
80
- if values[0].type == "STRING":
81
- self.state.chat_history.append(ChatMessage(role="ASSISTANT", text=values[0].value))
82
- elif values[0].type == "FUNCTION_CALL":
83
- self.state.prompt_iterations += 1
84
-
85
- function_call = values[0].value
86
- if function_call is not None:
87
- self.state.chat_history.append(
88
- ChatMessage(
89
- role="ASSISTANT",
90
- content=FunctionCallChatMessageContent(
91
- value=FunctionCallChatMessageContentValue(
92
- name=function_call.name,
93
- arguments=function_call.arguments,
94
- id=function_call.id,
95
- ),
96
- ),
97
- )
86
+ if output.name == InlinePromptNode.Outputs.results.name and output.value:
87
+ prompt_outputs = cast(List[PromptOutput], output.value)
88
+ chat_contents: List[ArrayChatMessageContentItem] = []
89
+ for prompt_output in prompt_outputs:
90
+ if prompt_output.type == "STRING":
91
+ chat_contents.append(StringChatMessageContent(value=prompt_output.value))
92
+ elif prompt_output.type == "FUNCTION_CALL" and prompt_output.value:
93
+ raw_function_call = prompt_output.value.model_dump()
94
+ if "state" in raw_function_call:
95
+ del raw_function_call["state"]
96
+ chat_contents.append(
97
+ FunctionCallChatMessageContent(
98
+ value=FunctionCallChatMessageContentValue.model_validate(raw_function_call)
98
99
  )
100
+ )
101
+
102
+ if len(chat_contents) == 1:
103
+ if chat_contents[0].type == "STRING":
104
+ self.state.chat_history.append(ChatMessage(role="ASSISTANT", text=chat_contents[0].value))
105
+ else:
106
+ self.state.chat_history.append(ChatMessage(role="ASSISTANT", content=chat_contents[0]))
107
+ else:
108
+ self.state.chat_history.append(
109
+ ChatMessage(role="ASSISTANT", content=ArrayChatMessageContent(value=chat_contents))
110
+ )
111
+
99
112
  yield output
100
113
 
101
114
 
115
+ class RouterNode(BaseNode[ToolCallingState]):
116
+ """Router node that handles routing to function nodes based on outputs."""
117
+
118
+ class Trigger(BaseNode.Trigger):
119
+ merge_behavior = MergeBehavior.AWAIT_ATTRIBUTES
120
+
121
+ def run(self) -> Iterator[BaseOutput]:
122
+ # Router node doesn't process outputs or create chat messages
123
+ # It just handles the routing logic via its ports
124
+ yield from []
125
+
126
+
102
127
  class DynamicSubworkflowDeploymentNode(SubworkflowDeploymentNode[ToolCallingState], FunctionCallNodeMixin):
103
128
  """Node that executes a deployment definition with function call output."""
104
129
 
@@ -225,42 +250,51 @@ class MCPNode(BaseNode[ToolCallingState], FunctionCallNodeMixin):
225
250
  yield from []
226
251
 
227
252
 
228
- def _hydrate_composio_tool_definition(tool_def: ComposioToolDefinition) -> ComposioToolDefinition:
253
+ class ElseNode(BaseNode[ToolCallingState]):
254
+ """Node that executes when no function conditions match."""
255
+
256
+ class Ports(BaseNode.Ports):
257
+ # Redefined in the create_else_node function, but defined here to resolve mypy errors
258
+ loop = Port.on_if(
259
+ ToolCallingState.current_prompt_output_index.less_than(1)
260
+ | ToolCallingState.current_function_calls_processed.greater_than(0)
261
+ )
262
+ end = Port.on_else()
263
+
264
+ def run(self) -> BaseNode.Outputs:
265
+ with self.state.__quiet__():
266
+ self.state.current_prompt_output_index += 1
267
+ return self.Outputs()
268
+
269
+
270
+ def _hydrate_composio_tool_definition(tool_def: ComposioToolDefinition) -> FunctionDefinition:
229
271
  """Hydrate a ComposioToolDefinition with detailed information from the Composio API.
230
272
 
231
273
  Args:
232
274
  tool_def: The basic ComposioToolDefinition to enhance
233
275
 
234
276
  Returns:
235
- ComposioToolDefinition with detailed parameters and description
277
+ FunctionDefinition with detailed parameters and description
236
278
  """
237
279
  try:
238
280
  composio_service = ComposioService()
239
281
  tool_details = composio_service.get_tool_by_slug(tool_def.action)
240
282
 
241
- # Extract toolkit information from API response
242
- toolkit_info = tool_details.get("toolkit", {})
243
- toolkit_slug = (
244
- toolkit_info.get("slug", tool_def.toolkit) if isinstance(toolkit_info, dict) else tool_def.toolkit
245
- )
246
-
247
- # Create a version of the tool definition with proper field extraction
248
- return ComposioToolDefinition(
249
- type=tool_def.type,
250
- toolkit=toolkit_slug.upper() if toolkit_slug else tool_def.toolkit,
251
- action=tool_details.get("slug", tool_def.action),
283
+ # Create a FunctionDefinition directly with proper field extraction
284
+ return FunctionDefinition(
285
+ name=tool_def.name,
252
286
  description=tool_details.get("description", tool_def.description),
253
- display_name=tool_details.get("name", tool_def.display_name),
254
- parameters=tool_details.get("input_parameters", tool_def.parameters),
255
- version=tool_details.get("version", tool_def.version),
256
- tags=tool_details.get("tags", tool_def.tags),
257
- user_id=tool_def.user_id,
287
+ parameters=tool_details.get("input_parameters", {}),
258
288
  )
259
289
 
260
290
  except Exception as e:
261
- # If hydration fails (including no API key), log and return original
291
+ # If hydration fails (including no API key), log and return basic function definition
262
292
  logger.warning(f"Failed to enhance Composio tool '{tool_def.action}': {e}")
263
- return tool_def
293
+ return FunctionDefinition(
294
+ name=tool_def.name,
295
+ description=tool_def.description,
296
+ parameters={},
297
+ )
264
298
 
265
299
 
266
300
  def hydrate_mcp_tool_definitions(server_def: MCPServer) -> List[MCPToolDefinition]:
@@ -303,8 +337,13 @@ def create_tool_router_node(
303
337
  return Port.on_if(
304
338
  LazyReference(
305
339
  lambda: (
306
- node.Outputs.results[0]["type"].equals("FUNCTION_CALL")
307
- & node.Outputs.results[0]["value"]["name"].equals(fn_name)
340
+ ToolCallingState.current_prompt_output_index.less_than(node.Outputs.results.length())
341
+ & node.Outputs.results[ToolCallingState.current_prompt_output_index]["type"].equals(
342
+ "FUNCTION_CALL"
343
+ )
344
+ & node.Outputs.results[ToolCallingState.current_prompt_output_index]["value"]["name"].equals(
345
+ fn_name
346
+ )
308
347
  )
309
348
  )
310
349
  )
@@ -313,13 +352,7 @@ def create_tool_router_node(
313
352
  if isinstance(function, ComposioToolDefinition):
314
353
  # Get Composio tool details and hydrate the function definition
315
354
  enhanced_function = _hydrate_composio_tool_definition(function)
316
- prompt_functions.append(
317
- FunctionDefinition(
318
- name=enhanced_function.name,
319
- description=enhanced_function.description,
320
- parameters=enhanced_function.parameters,
321
- )
322
- )
355
+ prompt_functions.append(enhanced_function)
323
356
  # Create port for this function (using original function for get_function_name)
324
357
  function_name = get_function_name(function)
325
358
  port = create_port_condition(function_name)
@@ -402,6 +435,69 @@ def create_tool_router_node(
402
435
  return node
403
436
 
404
437
 
438
+ def create_router_node(
439
+ functions: List[Tool],
440
+ tool_router_node: Type[ToolRouterNode],
441
+ ) -> Type[RouterNode]:
442
+ """Create a RouterNode with the same ports as ToolRouterNode."""
443
+
444
+ if functions and len(functions) > 0:
445
+ # Create dynamic ports and convert functions in a single loop
446
+ Ports = type("Ports", (), {})
447
+
448
+ def create_port_condition(fn_name):
449
+ return Port.on_if(
450
+ LazyReference(
451
+ lambda: (
452
+ ToolCallingState.current_prompt_output_index.less_than(
453
+ tool_router_node.Outputs.results.length()
454
+ )
455
+ & tool_router_node.Outputs.results[ToolCallingState.current_prompt_output_index]["type"].equals(
456
+ "FUNCTION_CALL"
457
+ )
458
+ & tool_router_node.Outputs.results[ToolCallingState.current_prompt_output_index]["value"][
459
+ "name"
460
+ ].equals(fn_name)
461
+ )
462
+ )
463
+ )
464
+
465
+ for function in functions:
466
+ if isinstance(function, ComposioToolDefinition):
467
+ function_name = get_function_name(function)
468
+ port = create_port_condition(function_name)
469
+ setattr(Ports, function_name, port)
470
+ elif isinstance(function, MCPServer):
471
+ tool_functions: List[MCPToolDefinition] = hydrate_mcp_tool_definitions(function)
472
+ for tool_function in tool_functions:
473
+ name = get_mcp_tool_name(tool_function)
474
+ port = create_port_condition(name)
475
+ setattr(Ports, name, port)
476
+ else:
477
+ function_name = get_function_name(function)
478
+ port = create_port_condition(function_name)
479
+ setattr(Ports, function_name, port)
480
+
481
+ # Add the else port for when no function conditions match
482
+ setattr(Ports, "default", Port.on_else())
483
+ else:
484
+ # If no functions exist, create a simple Ports class with just a default port
485
+ Ports = type("Ports", (), {"default": Port(default=True)})
486
+
487
+ node = cast(
488
+ Type[RouterNode],
489
+ type(
490
+ "RouterNode",
491
+ (RouterNode,),
492
+ {
493
+ "Ports": Ports,
494
+ "__module__": __name__,
495
+ },
496
+ ),
497
+ )
498
+ return node
499
+
500
+
405
501
  def create_function_node(
406
502
  function: ToolBase,
407
503
  tool_router_node: Type[ToolRouterNode],
@@ -485,6 +581,27 @@ def create_mcp_tool_node(
485
581
  return node
486
582
 
487
583
 
584
+ def create_else_node(
585
+ tool_router_node: Type[ToolRouterNode],
586
+ ) -> Type[ElseNode]:
587
+ class Ports(ElseNode.Ports):
588
+ loop = Port.on_if(
589
+ ToolCallingState.current_prompt_output_index.less_than(tool_router_node.Outputs.results.length())
590
+ | ToolCallingState.current_function_calls_processed.greater_than(0)
591
+ )
592
+ end = Port.on_else()
593
+
594
+ node = type(
595
+ f"{tool_router_node.__name__}_ElseNode",
596
+ (ElseNode,),
597
+ {
598
+ "Ports": Ports,
599
+ "__module__": __name__,
600
+ },
601
+ )
602
+ return node
603
+
604
+
488
605
  def get_function_name(function: ToolBase) -> str:
489
606
  if isinstance(function, DeploymentDefinition):
490
607
  name = str(function.deployment_id or function.deployment_name)
@@ -1,9 +1,11 @@
1
1
  from functools import cached_property
2
2
  from queue import Queue
3
+ from uuid import uuid4
3
4
  from typing import TYPE_CHECKING, Dict, List, Optional, Type
4
5
 
5
6
  from vellum import Vellum
6
7
  from vellum.workflows.context import ExecutionContext, get_execution_context
8
+ from vellum.workflows.events.types import ExternalParentContext
7
9
  from vellum.workflows.nodes.mocks import MockNodeExecution, MockNodeExecutionArg
8
10
  from vellum.workflows.outputs.base import BaseOutputs
9
11
  from vellum.workflows.references.constant import ConstantValueReference
@@ -25,8 +27,17 @@ class WorkflowContext:
25
27
  self._event_queue: Optional[Queue["WorkflowEvent"]] = None
26
28
  self._node_output_mocks_map: Dict[Type[BaseOutputs], List[MockNodeExecution]] = {}
27
29
  self._execution_context = get_execution_context()
28
- if not self._execution_context.parent_context and execution_context:
29
- self._execution_context = execution_context
30
+
31
+ if execution_context is not None:
32
+
33
+ self._execution_context.trace_id = execution_context.trace_id
34
+
35
+ if execution_context.parent_context is not None:
36
+ self._execution_context.parent_context = execution_context.parent_context
37
+
38
+ if self._execution_context.parent_context is None:
39
+ self._execution_context.parent_context = ExternalParentContext(span_id=uuid4())
40
+
30
41
  self._generated_files = generated_files
31
42
 
32
43
  @cached_property
@@ -2,13 +2,12 @@ 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, List, Literal, Optional, Union
5
+ from typing import Annotated, Any, Dict, Literal, Optional, Union
6
6
 
7
7
  from pydantic import BeforeValidator
8
8
 
9
9
  from vellum.client.core.pydantic_utilities import UniversalBaseModel
10
10
  from vellum.client.types.code_resource_definition import CodeResourceDefinition as ClientCodeResourceDefinition
11
- from vellum.client.types.vellum_secret import VellumSecret
12
11
  from vellum.workflows.constants import AuthorizationType
13
12
  from vellum.workflows.references.environment_variable import EnvironmentVariableReference
14
13
 
@@ -111,11 +110,6 @@ class ComposioToolDefinition(UniversalBaseModel):
111
110
  toolkit: str # "GITHUB", "SLACK", etc.
112
111
  action: str # Specific action like "GITHUB_CREATE_AN_ISSUE"
113
112
  description: str
114
-
115
- display_name: Optional[str] = None
116
- parameters: Optional[Dict[str, Any]] = None
117
- version: Optional[str] = None
118
- tags: Optional[List[str]] = None
119
113
  user_id: Optional[str] = None
120
114
 
121
115
  @property
@@ -125,12 +119,13 @@ class ComposioToolDefinition(UniversalBaseModel):
125
119
 
126
120
 
127
121
  class MCPServer(UniversalBaseModel):
122
+ type: Literal["MCP_SERVER"] = "MCP_SERVER"
128
123
  name: str
129
124
  url: str
130
125
  authorization_type: AuthorizationType = AuthorizationType.BEARER_TOKEN
131
126
  bearer_token_value: Optional[Union[str, EnvironmentVariableReference]] = None
132
127
  api_key_header_key: Optional[str] = None
133
- api_key_header_value: Optional[Union[str, VellumSecret]] = None
128
+ api_key_header_value: Optional[Union[str, EnvironmentVariableReference]] = None
134
129
 
135
130
  model_config = {"arbitrary_types_allowed": True}
136
131
 
@@ -1,7 +1,6 @@
1
1
  import pytest
2
2
  from uuid import UUID
3
3
 
4
- from vellum.client.types.vellum_secret import VellumSecret
5
4
  from vellum.workflows.constants import AuthorizationType
6
5
  from vellum.workflows.references.environment_variable import EnvironmentVariableReference
7
6
  from vellum.workflows.types.definition import ComposioToolDefinition, DeploymentDefinition, MCPServer, MCPToolDefinition
@@ -48,7 +47,7 @@ def test_composio_tool_definition_creation():
48
47
  assert composio_tool.toolkit == "GITHUB"
49
48
  assert composio_tool.action == "GITHUB_CREATE_AN_ISSUE"
50
49
  assert composio_tool.description == "Create a new issue in a GitHub repository"
51
- assert composio_tool.display_name is None
50
+ assert composio_tool.user_id is None
52
51
  assert composio_tool.name == "github_create_an_issue"
53
52
 
54
53
 
@@ -98,7 +97,7 @@ def test_mcp_tool_definition_creation_api_key():
98
97
  url="https://api.githubcopilot.com/mcp/",
99
98
  authorization_type=AuthorizationType.API_KEY,
100
99
  api_key_header_key="Authorization",
101
- api_key_header_value=VellumSecret(name="GITHUB_PERSONAL_ACCESS_TOKEN"),
100
+ api_key_header_value=EnvironmentVariableReference(name="GITHUB_PERSONAL_ACCESS_TOKEN"),
102
101
  ),
103
102
  parameters={
104
103
  "type": "object",
@@ -115,7 +114,7 @@ def test_mcp_tool_definition_creation_api_key():
115
114
  assert mcp_tool.server.url == "https://api.githubcopilot.com/mcp/"
116
115
  assert mcp_tool.server.authorization_type == AuthorizationType.API_KEY
117
116
  assert mcp_tool.server.api_key_header_key == "Authorization"
118
- assert isinstance(mcp_tool.server.api_key_header_value, VellumSecret)
117
+ assert isinstance(mcp_tool.server.api_key_header_value, EnvironmentVariableReference)
119
118
  assert mcp_tool.server.api_key_header_value.name == "GITHUB_PERSONAL_ACCESS_TOKEN"
120
119
  assert mcp_tool.parameters == {
121
120
  "type": "object",
@@ -221,7 +221,7 @@ def compile_workflow_deployment_function_definition(
221
221
  deployment = deployment_config["deployment"]
222
222
  release_tag = deployment_config["release_tag"]
223
223
 
224
- workflow_deployment_release = vellum_client.release_reviews.retrieve_workflow_deployment_release(
224
+ workflow_deployment_release = vellum_client.workflow_deployments.retrieve_workflow_deployment_release(
225
225
  deployment, release_tag
226
226
  )
227
227
 
@@ -448,7 +448,7 @@ def test_compile_workflow_deployment_function_definition__just_name():
448
448
  mock_release = Mock()
449
449
  mock_release.workflow_version.input_variables = []
450
450
  mock_release.description = "This is a test deployment"
451
- mock_client.release_reviews.retrieve_workflow_deployment_release.return_value = mock_release
451
+ mock_client.workflow_deployments.retrieve_workflow_deployment_release.return_value = mock_release
452
452
 
453
453
  deployment_config = {"deployment": "my_deployment", "release_tag": "latest"}
454
454
 
@@ -494,7 +494,7 @@ def test_compile_workflow_deployment_function_definition__all_args():
494
494
 
495
495
  mock_release.workflow_version.input_variables = mock_inputs
496
496
  mock_release.description = "This is a test deployment"
497
- mock_client.release_reviews.retrieve_workflow_deployment_release.return_value = mock_release
497
+ mock_client.workflow_deployments.retrieve_workflow_deployment_release.return_value = mock_release
498
498
 
499
499
  deployment_config = {"deployment": "my_deployment", "release_tag": "latest"}
500
500
 
@@ -562,7 +562,7 @@ def test_compile_workflow_deployment_function_definition__defaults():
562
562
 
563
563
  mock_release.workflow_version.input_variables = mock_inputs
564
564
  mock_release.description = "This is a test deployment"
565
- mock_client.release_reviews.retrieve_workflow_deployment_release.return_value = mock_release
565
+ mock_client.workflow_deployments.retrieve_workflow_deployment_release.return_value = mock_release
566
566
 
567
567
  deployment_config = {"deployment": "my_deployment", "release_tag": "latest"}
568
568
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 1.0.10
3
+ Version: 1.1.0
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0