vellum-ai 0.14.89__py3-none-any.whl → 1.0.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 (39) hide show
  1. vellum/__init__.py +1 -1
  2. vellum/client/__init__.py +2 -2
  3. vellum/client/core/client_wrapper.py +2 -2
  4. vellum/evaluations/resources.py +5 -5
  5. vellum/workflows/events/node.py +1 -1
  6. vellum/workflows/events/types.py +1 -1
  7. vellum/workflows/events/workflow.py +1 -1
  8. vellum/workflows/nodes/bases/tests/test_base_node.py +1 -1
  9. vellum/workflows/nodes/displayable/bases/base_prompt_node/node.py +1 -1
  10. vellum/workflows/nodes/displayable/bases/search_node.py +1 -1
  11. vellum/workflows/nodes/displayable/code_execution_node/node.py +1 -1
  12. vellum/workflows/nodes/displayable/guardrail_node/node.py +1 -1
  13. vellum/workflows/nodes/displayable/subworkflow_deployment_node/node.py +1 -1
  14. vellum/workflows/nodes/displayable/tool_calling_node/utils.py +83 -114
  15. vellum/workflows/nodes/experimental/__init__.py +2 -2
  16. vellum/workflows/state/base.py +1 -1
  17. vellum/workflows/state/delta.py +1 -1
  18. {vellum_ai-0.14.89.dist-info → vellum_ai-1.0.0.dist-info}/METADATA +1 -1
  19. {vellum_ai-0.14.89.dist-info → vellum_ai-1.0.0.dist-info}/RECORD +36 -39
  20. vellum_cli/config.py +1 -1
  21. vellum_cli/push.py +1 -1
  22. vellum_ee/workflows/display/base.py +0 -54
  23. vellum_ee/workflows/display/nodes/vellum/conditional_node.py +16 -2
  24. vellum_ee/workflows/display/nodes/vellum/tests/test_utils.py +3 -3
  25. vellum_ee/workflows/display/tests/test_base_workflow_display.py +2 -4
  26. vellum_ee/workflows/display/tests/workflow_serialization/generic_nodes/conftest.py +2 -2
  27. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_conditional_node_serialization.py +11 -11
  28. vellum_ee/workflows/display/vellum.py +2 -128
  29. vellum_ee/workflows/display/workflows/__init__.py +0 -1
  30. vellum_ee/workflows/display/workflows/base_workflow_display.py +1 -1
  31. vellum_ee/workflows/tests/local_workflow/display/nodes/final_output.py +1 -1
  32. vellum_ee/workflows/tests/local_workflow/display/nodes/templating_node.py +1 -1
  33. vellum_ee/workflows/tests/local_workflow/display/workflow.py +11 -14
  34. vellum/workflows/nodes/experimental/tool_calling_node/__init__.py +0 -3
  35. vellum/workflows/nodes/experimental/tool_calling_node/node.py +0 -3
  36. vellum_ee/workflows/display/workflows/vellum_workflow_display.py +0 -9
  37. {vellum_ai-0.14.89.dist-info → vellum_ai-1.0.0.dist-info}/LICENSE +0 -0
  38. {vellum_ai-0.14.89.dist-info → vellum_ai-1.0.0.dist-info}/WHEEL +0 -0
  39. {vellum_ai-0.14.89.dist-info → vellum_ai-1.0.0.dist-info}/entry_points.txt +0 -0
vellum/__init__.py CHANGED
@@ -3,7 +3,7 @@ from .plugins.utils import load_runtime_plugins
3
3
 
4
4
  load_runtime_plugins()
5
5
 
6
- from .types import (
6
+ from .client.types import (
7
7
  AdHocExecutePromptEvent,
8
8
  AdHocExpandMeta,
9
9
  AdHocFulfilledPromptExecutionMeta,
vellum/client/__init__.py CHANGED
@@ -128,7 +128,7 @@ class Vellum:
128
128
  self,
129
129
  *,
130
130
  environment: VellumEnvironment = VellumEnvironment.PRODUCTION,
131
- api_version: typing.Optional[ApiVersionEnum] = os.getenv("VELLUM_API_VERSION", "2024-10-25"),
131
+ api_version: typing.Optional[ApiVersionEnum] = os.getenv("VELLUM_API_VERSION", "2025-07-30"),
132
132
  api_key: str,
133
133
  timeout: typing.Optional[float] = None,
134
134
  follow_redirects: typing.Optional[bool] = True,
@@ -1562,7 +1562,7 @@ class AsyncVellum:
1562
1562
  self,
1563
1563
  *,
1564
1564
  environment: VellumEnvironment = VellumEnvironment.PRODUCTION,
1565
- api_version: typing.Optional[ApiVersionEnum] = os.getenv("VELLUM_API_VERSION", "2024-10-25"),
1565
+ api_version: typing.Optional[ApiVersionEnum] = os.getenv("VELLUM_API_VERSION", "2025-07-30"),
1566
1566
  api_key: str,
1567
1567
  timeout: typing.Optional[float] = None,
1568
1568
  follow_redirects: typing.Optional[bool] = True,
@@ -25,10 +25,10 @@ class BaseClientWrapper:
25
25
 
26
26
  def get_headers(self) -> typing.Dict[str, str]:
27
27
  headers: typing.Dict[str, str] = {
28
- "User-Agent": "vellum-ai/0.14.89",
28
+ "User-Agent": "vellum-ai/1.0.0",
29
29
  "X-Fern-Language": "Python",
30
30
  "X-Fern-SDK-Name": "vellum-ai",
31
- "X-Fern-SDK-Version": "0.14.89",
31
+ "X-Fern-SDK-Version": "1.0.0",
32
32
  }
33
33
  if self._api_version is not None:
34
34
  headers["X-API-Version"] = self._api_version
@@ -8,11 +8,7 @@ from typing import Callable, Generator, Iterable, List, cast
8
8
 
9
9
  from vellum import TestSuiteRunMetricNumberOutput, TestSuiteRunRead
10
10
  from vellum.client import OMIT, Vellum
11
- from vellum.evaluations.constants import DEFAULT_MAX_POLLING_DURATION_MS, DEFAULT_POLLING_INTERVAL_MS
12
- from vellum.evaluations.exceptions import TestSuiteRunResultsException
13
- from vellum.evaluations.utils.env import get_api_key
14
- from vellum.evaluations.utils.paginator import PaginatedResults, get_all_results
15
- from vellum.types import (
11
+ from vellum.client.types import (
16
12
  ExternalTestCaseExecutionRequest,
17
13
  NamedTestCaseVariableValueRequest,
18
14
  TestCaseVariableValue,
@@ -22,6 +18,10 @@ from vellum.types import (
22
18
  TestSuiteRunMetricOutput,
23
19
  TestSuiteRunState,
24
20
  )
21
+ from vellum.evaluations.constants import DEFAULT_MAX_POLLING_DURATION_MS, DEFAULT_POLLING_INTERVAL_MS
22
+ from vellum.evaluations.exceptions import TestSuiteRunResultsException
23
+ from vellum.evaluations.utils.env import get_api_key
24
+ from vellum.evaluations.utils.paginator import PaginatedResults, get_all_results
25
25
  from vellum.utils.typing import cast_not_optional
26
26
  from vellum.utils.uuid import is_valid_uuid
27
27
 
@@ -2,7 +2,7 @@ from typing import TYPE_CHECKING, Any, Dict, Generic, List, Literal, Optional, S
2
2
 
3
3
  from pydantic import SerializerFunctionWrapHandler, field_serializer, model_serializer
4
4
 
5
- from vellum.core.pydantic_utilities import UniversalBaseModel
5
+ from vellum.client.core.pydantic_utilities import UniversalBaseModel
6
6
  from vellum.workflows.errors import WorkflowError
7
7
  from vellum.workflows.expressions.accessor import AccessorExpression
8
8
  from vellum.workflows.outputs.base import BaseOutput
@@ -6,7 +6,7 @@ from typing import Annotated, Any, Literal, Optional, Union, get_args
6
6
  from pydantic import Field, GetCoreSchemaHandler, Tag, ValidationInfo
7
7
  from pydantic_core import CoreSchema, core_schema
8
8
 
9
- from vellum.core.pydantic_utilities import UniversalBaseModel
9
+ from vellum.client.core.pydantic_utilities import UniversalBaseModel
10
10
  from vellum.workflows.state.encoder import DefaultStateEncoder
11
11
  from vellum.workflows.types.definition import VellumCodeResourceDefinition
12
12
  from vellum.workflows.types.utils import datetime_now
@@ -4,7 +4,7 @@ from typing_extensions import TypeGuard
4
4
 
5
5
  from pydantic import field_serializer
6
6
 
7
- from vellum.core.pydantic_utilities import UniversalBaseModel
7
+ from vellum.client.core.pydantic_utilities import UniversalBaseModel
8
8
  from vellum.workflows.errors import WorkflowError
9
9
  from vellum.workflows.outputs.base import BaseOutput
10
10
  from vellum.workflows.references import ExternalInputReference
@@ -2,8 +2,8 @@ import pytest
2
2
  from uuid import UUID
3
3
  from typing import Optional, Set
4
4
 
5
+ from vellum.client.core.pydantic_utilities import UniversalBaseModel
5
6
  from vellum.client.types.string_vellum_value_request import StringVellumValueRequest
6
- from vellum.core.pydantic_utilities import UniversalBaseModel
7
7
  from vellum.workflows.constants import undefined
8
8
  from vellum.workflows.descriptors.tests.test_utils import FixtureState
9
9
  from vellum.workflows.inputs.base import BaseInputs
@@ -2,8 +2,8 @@ from abc import abstractmethod
2
2
  from typing import ClassVar, Generator, Generic, Iterator, List, Optional, Union
3
3
 
4
4
  from vellum import AdHocExecutePromptEvent, ExecutePromptEvent, PromptOutput
5
+ from vellum.client.core import RequestOptions
5
6
  from vellum.client.core.api_error import ApiError
6
- from vellum.core import RequestOptions
7
7
  from vellum.workflows.errors.types import WorkflowErrorCode, vellum_error_to_workflow_error
8
8
  from vellum.workflows.events.node import NodeExecutionStreamingEvent
9
9
  from vellum.workflows.exceptions import NodeException
@@ -11,7 +11,7 @@ from vellum import (
11
11
  SearchResultMergingRequest,
12
12
  SearchWeightsRequest,
13
13
  )
14
- from vellum.core import ApiError, RequestOptions
14
+ from vellum.client.core import ApiError, RequestOptions
15
15
  from vellum.workflows.errors import WorkflowErrorCode
16
16
  from vellum.workflows.exceptions import NodeException
17
17
  from vellum.workflows.nodes.bases import BaseNode
@@ -20,9 +20,9 @@ from vellum import (
20
20
  VellumError,
21
21
  VellumValue,
22
22
  )
23
+ from vellum.client.core import RequestOptions
23
24
  from vellum.client.core.api_error import ApiError
24
25
  from vellum.client.types.code_executor_secret_input import CodeExecutorSecretInput
25
- from vellum.core import RequestOptions
26
26
  from vellum.workflows.errors.types import WorkflowErrorCode
27
27
  from vellum.workflows.exceptions import NodeException
28
28
  from vellum.workflows.nodes.bases import BaseNode
@@ -3,7 +3,7 @@ from typing import Any, ClassVar, Dict, Generic, List, Optional, Union, cast
3
3
 
4
4
  from vellum import ChatHistoryInput, ChatMessage, JsonInput, MetricDefinitionInput, NumberInput, StringInput
5
5
  from vellum.client import ApiError
6
- from vellum.core import RequestOptions
6
+ from vellum.client.core import RequestOptions
7
7
  from vellum.workflows.constants import LATEST_RELEASE_TAG
8
8
  from vellum.workflows.errors.types import WorkflowErrorCode
9
9
  from vellum.workflows.exceptions import NodeException
@@ -12,9 +12,9 @@ from vellum import (
12
12
  WorkflowRequestNumberInputRequest,
13
13
  WorkflowRequestStringInputRequest,
14
14
  )
15
+ from vellum.client.core import RequestOptions
15
16
  from vellum.client.core.api_error import ApiError
16
17
  from vellum.client.types.chat_message_request import ChatMessageRequest
17
- from vellum.core import RequestOptions
18
18
  from vellum.workflows.constants import LATEST_RELEASE_TAG, OMIT
19
19
  from vellum.workflows.context import get_execution_context
20
20
  from vellum.workflows.errors import WorkflowErrorCode
@@ -1,5 +1,5 @@
1
1
  import json
2
- from typing import Any, Iterator, List, Optional, Type, cast
2
+ from typing import Any, Callable, Iterator, List, Optional, Type, cast
3
3
 
4
4
  from pydash import snake_case
5
5
 
@@ -9,33 +9,26 @@ from vellum.client.types.function_call_chat_message_content_value import Functio
9
9
  from vellum.client.types.prompt_output import PromptOutput
10
10
  from vellum.client.types.string_chat_message_content import StringChatMessageContent
11
11
  from vellum.client.types.variable_prompt_block import VariablePromptBlock
12
- from vellum.workflows.context import execution_context, get_parent_context
13
12
  from vellum.workflows.errors.types import WorkflowErrorCode
14
- from vellum.workflows.events.workflow import is_workflow_event
15
13
  from vellum.workflows.exceptions import NodeException
14
+ from vellum.workflows.inputs import BaseInputs
16
15
  from vellum.workflows.nodes.bases import BaseNode
16
+ from vellum.workflows.nodes.core.inline_subworkflow_node.node import InlineSubworkflowNode
17
17
  from vellum.workflows.nodes.displayable.inline_prompt_node.node import InlinePromptNode
18
18
  from vellum.workflows.nodes.displayable.subworkflow_deployment_node.node import SubworkflowDeploymentNode
19
19
  from vellum.workflows.nodes.displayable.tool_calling_node.state import ToolCallingState
20
- from vellum.workflows.outputs.base import BaseOutput, BaseOutputs
20
+ from vellum.workflows.outputs.base import BaseOutput
21
21
  from vellum.workflows.ports.port import Port
22
22
  from vellum.workflows.references.lazy import LazyReference
23
- from vellum.workflows.state.context import WorkflowContext
23
+ from vellum.workflows.state import BaseState
24
24
  from vellum.workflows.state.encoder import DefaultStateEncoder
25
25
  from vellum.workflows.types.core import EntityInputsInterface, MergeBehavior, Tool
26
26
  from vellum.workflows.types.definition import DeploymentDefinition
27
27
  from vellum.workflows.types.generics import is_workflow_class
28
- from vellum.workflows.workflows.event_filters import all_workflow_event_filter
29
28
 
30
29
  CHAT_HISTORY_VARIABLE = "chat_history"
31
30
 
32
31
 
33
- class FunctionNode(BaseNode):
34
- """Node that executes a specific function."""
35
-
36
- pass
37
-
38
-
39
32
  class ToolRouterNode(InlinePromptNode[ToolCallingState]):
40
33
  max_prompt_iterations: Optional[int] = 5
41
34
 
@@ -120,6 +113,76 @@ class DynamicSubworkflowDeploymentNode(SubworkflowDeploymentNode[ToolCallingStat
120
113
  )
121
114
 
122
115
 
116
+ class DynamicInlineSubworkflowNode(InlineSubworkflowNode[ToolCallingState, BaseInputs, BaseState]):
117
+ """Node that executes an inline subworkflow with function call output."""
118
+
119
+ function_call_output: List[PromptOutput]
120
+
121
+ def run(self) -> Iterator[BaseOutput]:
122
+ if self.function_call_output and len(self.function_call_output) > 0:
123
+ function_call = self.function_call_output[0]
124
+ if function_call.type == "FUNCTION_CALL" and function_call.value is not None:
125
+ arguments = function_call.value.arguments
126
+ else:
127
+ arguments = {}
128
+ else:
129
+ arguments = {}
130
+
131
+ self.subworkflow_inputs = arguments # type: ignore[misc]
132
+
133
+ # Call the parent run method to execute the subworkflow with proper streaming
134
+ outputs = {}
135
+
136
+ for output in super().run():
137
+ if output.is_fulfilled:
138
+ outputs[output.name] = output.value
139
+ yield output
140
+
141
+ # Add the result to the chat history
142
+ self.state.chat_history.append(
143
+ ChatMessage(
144
+ role="FUNCTION",
145
+ content=StringChatMessageContent(value=json.dumps(outputs, cls=DefaultStateEncoder)),
146
+ )
147
+ )
148
+
149
+
150
+ class FunctionNode(BaseNode[ToolCallingState]):
151
+ """Node that executes a regular Python function with function call output."""
152
+
153
+ function_call_output: List[PromptOutput]
154
+ function_definition: Callable[..., Any]
155
+
156
+ def run(self) -> Iterator[BaseOutput]:
157
+ if self.function_call_output and len(self.function_call_output) > 0:
158
+ function_call = self.function_call_output[0]
159
+ if function_call.type == "FUNCTION_CALL" and function_call.value is not None:
160
+ arguments = function_call.value.arguments
161
+ else:
162
+ arguments = {}
163
+ else:
164
+ arguments = {}
165
+
166
+ try:
167
+ result = self.function_definition(**arguments)
168
+ except Exception as e:
169
+ function_name = self.function_definition.__name__
170
+ raise NodeException(
171
+ message=f"Error executing function '{function_name}': {str(e)}",
172
+ code=WorkflowErrorCode.NODE_EXECUTION,
173
+ )
174
+
175
+ # Add the result to the chat history
176
+ self.state.chat_history.append(
177
+ ChatMessage(
178
+ role="FUNCTION",
179
+ content=StringChatMessageContent(value=json.dumps(result, cls=DefaultStateEncoder)),
180
+ )
181
+ )
182
+
183
+ yield from []
184
+
185
+
123
186
  def create_tool_router_node(
124
187
  ml_model: str,
125
188
  blocks: List[PromptBlock],
@@ -191,7 +254,7 @@ def create_tool_router_node(
191
254
  def create_function_node(
192
255
  function: Tool,
193
256
  tool_router_node: Type[ToolRouterNode],
194
- ) -> Type[FunctionNode]:
257
+ ) -> Type[BaseNode]:
195
258
  """
196
259
  Create a FunctionNode class for a given function.
197
260
 
@@ -220,117 +283,23 @@ def create_function_node(
220
283
  return node
221
284
 
222
285
  elif is_workflow_class(function):
223
- # Create a class-level wrapper that calls the original function
224
- def execute_inline_workflow_function(self) -> BaseNode.Outputs:
225
- function_call_output = self.state.meta.node_outputs.get(tool_router_node.Outputs.results)
226
- if function_call_output and len(function_call_output) > 0:
227
- function_call = function_call_output[0]
228
- arguments = function_call.value.arguments
229
- else:
230
- arguments = {}
231
-
232
- # Call the function based on its type
233
- inputs_instance = function.get_inputs_class()(**arguments)
234
-
235
- with execution_context(parent_context=get_parent_context()):
236
- workflow = function(
237
- parent_state=self.state,
238
- context=WorkflowContext.create_from(self._context),
239
- )
240
- subworkflow_stream = workflow.stream(
241
- inputs=inputs_instance,
242
- event_filter=all_workflow_event_filter,
243
- node_output_mocks=self._context._get_all_node_output_mocks(),
244
- )
245
-
246
- outputs: Optional[BaseOutputs] = None
247
- exception: Optional[NodeException] = None
248
-
249
- for event in subworkflow_stream:
250
- self._context._emit_subworkflow_event(event)
251
- if exception:
252
- continue
253
-
254
- if not is_workflow_event(event):
255
- continue
256
- if event.workflow_definition != function:
257
- continue
258
-
259
- if event.name == "workflow.execution.fulfilled":
260
- outputs = event.outputs
261
- elif event.name == "workflow.execution.rejected":
262
- exception = NodeException.of(event.error)
263
- elif event.name == "workflow.execution.paused":
264
- exception = NodeException(
265
- code=WorkflowErrorCode.INVALID_OUTPUTS,
266
- message="Subworkflow unexpectedly paused",
267
- )
268
-
269
- if exception:
270
- raise exception
271
-
272
- if outputs is None:
273
- raise NodeException(
274
- message="Expected to receive outputs from inline subworkflow",
275
- code=WorkflowErrorCode.INVALID_OUTPUTS,
276
- )
277
-
278
- result = outputs
279
-
280
- self.state.chat_history.append(
281
- ChatMessage(
282
- role="FUNCTION",
283
- content=StringChatMessageContent(value=json.dumps(result, cls=DefaultStateEncoder)),
284
- )
285
- )
286
-
287
- return self.Outputs()
288
-
289
- # Create BaseNode for workflow functions
290
286
  node = type(
291
- f"InlineWorkflowNode_{function.__name__}",
292
- (FunctionNode,),
287
+ f"DynamicInlineSubworkflowNode_{function.__name__}",
288
+ (DynamicInlineSubworkflowNode,),
293
289
  {
294
- "run": execute_inline_workflow_function,
290
+ "subworkflow": function,
291
+ "function_call_output": tool_router_node.Outputs.results,
295
292
  "__module__": __name__,
296
293
  },
297
294
  )
298
295
  else:
299
- # For regular functions, call them directly
300
- def execute_regular_function(self) -> BaseNode.Outputs:
301
- # Get the function call from the tool router output
302
- function_call_output = self.state.meta.node_outputs.get(tool_router_node.Outputs.results)
303
- if function_call_output and len(function_call_output) > 0:
304
- function_call = function_call_output[0]
305
- arguments = function_call.value.arguments
306
- else:
307
- arguments = {}
308
-
309
- # Call the function directly
310
- try:
311
- result = function(**arguments)
312
- except Exception as e:
313
- raise NodeException(
314
- message=f"Error executing function '{function.__name__}': {str(e)}",
315
- code=WorkflowErrorCode.NODE_EXECUTION,
316
- )
317
-
318
- # Add the result to the chat history
319
- self.state.chat_history.append(
320
- ChatMessage(
321
- role="FUNCTION",
322
- content=StringChatMessageContent(value=json.dumps(result, cls=DefaultStateEncoder)),
323
- )
324
- )
325
-
326
- return self.Outputs()
327
-
328
- # Create BaseNode for regular functions
296
+ # For regular functions, use FunctionNode
329
297
  node = type(
330
298
  f"FunctionNode_{function.__name__}",
331
299
  (FunctionNode,),
332
300
  {
333
- "run": execute_regular_function,
301
+ "function_definition": lambda self, **kwargs: function(**kwargs),
302
+ "function_call_output": tool_router_node.Outputs.results,
334
303
  "__module__": __name__,
335
304
  },
336
305
  )
@@ -1,3 +1,3 @@
1
- from ..displayable.tool_calling_node import ToolCallingNode
1
+ from .openai_chat_completion_node import OpenAIChatCompletionNode
2
2
 
3
- __all__ = ["ToolCallingNode"]
3
+ __all__ = ["OpenAIChatCompletionNode"]
@@ -27,7 +27,7 @@ from typing_extensions import dataclass_transform
27
27
  from pydantic import GetCoreSchemaHandler, ValidationInfo, field_serializer, field_validator
28
28
  from pydantic_core import core_schema
29
29
 
30
- from vellum.core.pydantic_utilities import UniversalBaseModel
30
+ from vellum.client.core.pydantic_utilities import UniversalBaseModel
31
31
  from vellum.utils.uuid import is_valid_uuid
32
32
  from vellum.workflows.constants import undefined
33
33
  from vellum.workflows.inputs.base import BaseInputs
@@ -1,6 +1,6 @@
1
1
  from typing import Any, Literal, Union
2
2
 
3
- from vellum.core.pydantic_utilities import UniversalBaseModel
3
+ from vellum.client.core.pydantic_utilities import UniversalBaseModel
4
4
 
5
5
 
6
6
  class BaseStateDelta(UniversalBaseModel):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.14.89
3
+ Version: 1.0.0
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0