vellum-ai 0.14.81__py3-none-any.whl → 0.14.83__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 (55) hide show
  1. vellum/__init__.py +10 -0
  2. vellum/client/README.md +1 -9
  3. vellum/client/__init__.py +44 -24
  4. vellum/client/core/client_wrapper.py +2 -1
  5. vellum/client/core/http_client.py +0 -2
  6. vellum/client/core/jsonable_encoder.py +0 -1
  7. vellum/client/core/pydantic_utilities.py +1 -3
  8. vellum/client/core/serialization.py +1 -2
  9. vellum/client/reference.md +8 -0
  10. vellum/client/resources/ad_hoc/client.py +20 -12
  11. vellum/client/resources/deployments/client.py +6 -2
  12. vellum/client/resources/documents/client.py +10 -0
  13. vellum/client/types/__init__.py +10 -0
  14. vellum/client/types/container_image_build_config.py +1 -0
  15. vellum/client/types/document_read.py +5 -0
  16. vellum/client/types/execution_thinking_vellum_value.py +31 -0
  17. vellum/client/types/execution_vellum_value.py +2 -0
  18. vellum/client/types/google_vertex_ai_vectorizer_gemini_embedding_001.py +21 -0
  19. vellum/client/types/google_vertex_ai_vectorizer_gemini_embedding_001_request.py +21 -0
  20. vellum/client/types/indexing_config_vectorizer.py +2 -0
  21. vellum/client/types/indexing_config_vectorizer_request.py +2 -0
  22. vellum/client/types/prompt_output.py +4 -1
  23. vellum/client/types/thinking_vellum_value.py +25 -0
  24. vellum/client/types/thinking_vellum_value_request.py +25 -0
  25. vellum/client/types/vellum_value.py +2 -0
  26. vellum/client/types/vellum_value_request.py +2 -0
  27. vellum/client/types/vellum_variable_type.py +1 -0
  28. vellum/client/types/workflow_sandbox_example.py +2 -0
  29. vellum/types/execution_thinking_vellum_value.py +3 -0
  30. vellum/types/google_vertex_ai_vectorizer_gemini_embedding_001.py +3 -0
  31. vellum/types/google_vertex_ai_vectorizer_gemini_embedding_001_request.py +3 -0
  32. vellum/types/thinking_vellum_value.py +3 -0
  33. vellum/types/thinking_vellum_value_request.py +3 -0
  34. vellum/workflows/nodes/displayable/__init__.py +2 -0
  35. vellum/workflows/nodes/displayable/inline_prompt_node/node.py +3 -0
  36. vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +3 -0
  37. vellum/workflows/nodes/displayable/tool_calling_node/__init__.py +3 -0
  38. vellum/workflows/nodes/{experimental → displayable}/tool_calling_node/node.py +4 -21
  39. vellum/workflows/nodes/{experimental → displayable}/tool_calling_node/tests/test_node.py +1 -1
  40. vellum/workflows/nodes/{experimental → displayable}/tool_calling_node/tests/test_utils.py +1 -1
  41. vellum/workflows/nodes/{experimental → displayable}/tool_calling_node/utils.py +22 -57
  42. vellum/workflows/nodes/experimental/__init__.py +1 -1
  43. vellum/workflows/nodes/experimental/tool_calling_node/__init__.py +1 -1
  44. vellum/workflows/state/encoder.py +2 -2
  45. {vellum_ai-0.14.81.dist-info → vellum_ai-0.14.83.dist-info}/METADATA +1 -1
  46. {vellum_ai-0.14.81.dist-info → vellum_ai-0.14.83.dist-info}/RECORD +55 -44
  47. vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py +1 -104
  48. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py +1 -6
  49. vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py +1 -17
  50. vellum_ee/workflows/display/workflows/base_workflow_display.py +10 -5
  51. vellum_ee/workflows/tests/test_serialize_module.py +1 -1
  52. /vellum/workflows/nodes/{experimental → displayable}/tool_calling_node/tests/__init__.py +0 -0
  53. {vellum_ai-0.14.81.dist-info → vellum_ai-0.14.83.dist-info}/LICENSE +0 -0
  54. {vellum_ai-0.14.81.dist-info → vellum_ai-0.14.83.dist-info}/WHEEL +0 -0
  55. {vellum_ai-0.14.81.dist-info → vellum_ai-0.14.83.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,21 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.pydantic_utilities import UniversalBaseModel
4
+ import typing
5
+ from .google_vertex_ai_vectorizer_config import GoogleVertexAiVectorizerConfig
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
+ import pydantic
8
+
9
+
10
+ class GoogleVertexAiVectorizerGeminiEmbedding001(UniversalBaseModel):
11
+ model_name: typing.Literal["gemini-embedding-001"] = "gemini-embedding-001"
12
+ config: GoogleVertexAiVectorizerConfig
13
+
14
+ if IS_PYDANTIC_V2:
15
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
16
+ else:
17
+
18
+ class Config:
19
+ frozen = True
20
+ smart_union = True
21
+ extra = pydantic.Extra.allow
@@ -0,0 +1,21 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.pydantic_utilities import UniversalBaseModel
4
+ import typing
5
+ from .google_vertex_ai_vectorizer_config_request import GoogleVertexAiVectorizerConfigRequest
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
+ import pydantic
8
+
9
+
10
+ class GoogleVertexAiVectorizerGeminiEmbedding001Request(UniversalBaseModel):
11
+ model_name: typing.Literal["gemini-embedding-001"] = "gemini-embedding-001"
12
+ config: GoogleVertexAiVectorizerConfigRequest
13
+
14
+ if IS_PYDANTIC_V2:
15
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
16
+ else:
17
+
18
+ class Config:
19
+ frozen = True
20
+ smart_union = True
21
+ extra = pydantic.Extra.allow
@@ -16,6 +16,7 @@ from .google_vertex_ai_vectorizer_text_embedding_004 import GoogleVertexAiVector
16
16
  from .google_vertex_ai_vectorizer_text_multilingual_embedding_002 import (
17
17
  GoogleVertexAiVectorizerTextMultilingualEmbedding002,
18
18
  )
19
+ from .google_vertex_ai_vectorizer_gemini_embedding_001 import GoogleVertexAiVectorizerGeminiEmbedding001
19
20
  from .fast_embed_vectorizer_baai_bge_small_en_v_15 import FastEmbedVectorizerBaaiBgeSmallEnV15
20
21
 
21
22
  IndexingConfigVectorizer = typing.Union[
@@ -28,5 +29,6 @@ IndexingConfigVectorizer = typing.Union[
28
29
  HkunlpInstructorXlVectorizer,
29
30
  GoogleVertexAiVectorizerTextEmbedding004,
30
31
  GoogleVertexAiVectorizerTextMultilingualEmbedding002,
32
+ GoogleVertexAiVectorizerGeminiEmbedding001,
31
33
  FastEmbedVectorizerBaaiBgeSmallEnV15,
32
34
  ]
@@ -16,6 +16,7 @@ from .google_vertex_ai_vectorizer_text_embedding_004_request import GoogleVertex
16
16
  from .google_vertex_ai_vectorizer_text_multilingual_embedding_002_request import (
17
17
  GoogleVertexAiVectorizerTextMultilingualEmbedding002Request,
18
18
  )
19
+ from .google_vertex_ai_vectorizer_gemini_embedding_001_request import GoogleVertexAiVectorizerGeminiEmbedding001Request
19
20
  from .fast_embed_vectorizer_baai_bge_small_en_v_15_request import FastEmbedVectorizerBaaiBgeSmallEnV15Request
20
21
 
21
22
  IndexingConfigVectorizerRequest = typing.Union[
@@ -28,5 +29,6 @@ IndexingConfigVectorizerRequest = typing.Union[
28
29
  HkunlpInstructorXlVectorizerRequest,
29
30
  GoogleVertexAiVectorizerTextEmbedding004Request,
30
31
  GoogleVertexAiVectorizerTextMultilingualEmbedding002Request,
32
+ GoogleVertexAiVectorizerGeminiEmbedding001Request,
31
33
  FastEmbedVectorizerBaaiBgeSmallEnV15Request,
32
34
  ]
@@ -5,5 +5,8 @@ from .string_vellum_value import StringVellumValue
5
5
  from .json_vellum_value import JsonVellumValue
6
6
  from .error_vellum_value import ErrorVellumValue
7
7
  from .function_call_vellum_value import FunctionCallVellumValue
8
+ from .thinking_vellum_value import ThinkingVellumValue
8
9
 
9
- PromptOutput = typing.Union[StringVellumValue, JsonVellumValue, ErrorVellumValue, FunctionCallVellumValue]
10
+ PromptOutput = typing.Union[
11
+ StringVellumValue, JsonVellumValue, ErrorVellumValue, FunctionCallVellumValue, ThinkingVellumValue
12
+ ]
@@ -0,0 +1,25 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.pydantic_utilities import UniversalBaseModel
4
+ import typing
5
+ from .string_vellum_value import StringVellumValue
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
+ import pydantic
8
+
9
+
10
+ class ThinkingVellumValue(UniversalBaseModel):
11
+ """
12
+ A value representing Thinking mode output.
13
+ """
14
+
15
+ type: typing.Literal["THINKING"] = "THINKING"
16
+ value: StringVellumValue
17
+
18
+ if IS_PYDANTIC_V2:
19
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
20
+ else:
21
+
22
+ class Config:
23
+ frozen = True
24
+ smart_union = True
25
+ extra = pydantic.Extra.allow
@@ -0,0 +1,25 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from ..core.pydantic_utilities import UniversalBaseModel
4
+ import typing
5
+ from .string_vellum_value_request import StringVellumValueRequest
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
+ import pydantic
8
+
9
+
10
+ class ThinkingVellumValueRequest(UniversalBaseModel):
11
+ """
12
+ A value representing Thinking mode output.
13
+ """
14
+
15
+ type: typing.Literal["THINKING"] = "THINKING"
16
+ value: StringVellumValueRequest
17
+
18
+ if IS_PYDANTIC_V2:
19
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
20
+ else:
21
+
22
+ class Config:
23
+ frozen = True
24
+ smart_union = True
25
+ extra = pydantic.Extra.allow
@@ -12,6 +12,7 @@ from .function_call_vellum_value import FunctionCallVellumValue
12
12
  from .error_vellum_value import ErrorVellumValue
13
13
  from .chat_history_vellum_value import ChatHistoryVellumValue
14
14
  from .search_results_vellum_value import SearchResultsVellumValue
15
+ from .thinking_vellum_value import ThinkingVellumValue
15
16
  import typing
16
17
 
17
18
  if typing.TYPE_CHECKING:
@@ -28,4 +29,5 @@ VellumValue = typing.Union[
28
29
  "ArrayVellumValue",
29
30
  ChatHistoryVellumValue,
30
31
  SearchResultsVellumValue,
32
+ ThinkingVellumValue,
31
33
  ]
@@ -12,6 +12,7 @@ from .function_call_vellum_value_request import FunctionCallVellumValueRequest
12
12
  from .error_vellum_value_request import ErrorVellumValueRequest
13
13
  from .chat_history_vellum_value_request import ChatHistoryVellumValueRequest
14
14
  from .search_results_vellum_value_request import SearchResultsVellumValueRequest
15
+ from .thinking_vellum_value_request import ThinkingVellumValueRequest
15
16
  import typing
16
17
 
17
18
  if typing.TYPE_CHECKING:
@@ -28,4 +29,5 @@ VellumValueRequest = typing.Union[
28
29
  "ArrayVellumValueRequest",
29
30
  ChatHistoryVellumValueRequest,
30
31
  SearchResultsVellumValueRequest,
32
+ ThinkingVellumValueRequest,
31
33
  ]
@@ -16,6 +16,7 @@ VellumVariableType = typing.Union[
16
16
  "AUDIO",
17
17
  "DOCUMENT",
18
18
  "NULL",
19
+ "THINKING",
19
20
  ],
20
21
  typing.Any,
21
22
  ]
@@ -11,6 +11,8 @@ class WorkflowSandboxExample(UniversalBaseModel):
11
11
  label: str
12
12
  description: typing.Optional[str] = None
13
13
  icon_name: typing.Optional[str] = None
14
+ ui_image_url: typing.Optional[str] = None
15
+ code_image_url: typing.Optional[str] = None
14
16
 
15
17
  if IS_PYDANTIC_V2:
16
18
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.execution_thinking_vellum_value import *
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.google_vertex_ai_vectorizer_gemini_embedding_001 import *
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.google_vertex_ai_vectorizer_gemini_embedding_001_request import *
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.thinking_vellum_value import *
@@ -0,0 +1,3 @@
1
+ # WARNING: This file will be removed in a future release. Please import from "vellum.client" instead.
2
+
3
+ from vellum.client.types.thinking_vellum_value_request import *
@@ -13,6 +13,7 @@ from .note_node import NoteNode
13
13
  from .prompt_deployment_node import PromptDeploymentNode
14
14
  from .search_node import SearchNode
15
15
  from .subworkflow_deployment_node import SubworkflowDeploymentNode
16
+ from .tool_calling_node import ToolCallingNode
16
17
 
17
18
  __all__ = [
18
19
  "APINode",
@@ -29,5 +30,6 @@ __all__ = [
29
30
  "PromptDeploymentNode",
30
31
  "SearchNode",
31
32
  "TemplatingNode",
33
+ "ToolCallingNode",
32
34
  "FinalOutputNode",
33
35
  ]
@@ -63,6 +63,9 @@ class InlinePromptNode(BaseInlinePromptNode[StateType]):
63
63
  json_output = output.value
64
64
  elif output.type == "FUNCTION_CALL":
65
65
  string_outputs.append(output.value.model_dump_json(indent=4))
66
+ elif output.type == "THINKING":
67
+ if output.value.type == "STRING":
68
+ string_outputs.append(output.value.value)
66
69
  else:
67
70
  string_outputs.append(output.value.message)
68
71
 
@@ -65,6 +65,9 @@ class PromptDeploymentNode(BasePromptDeploymentNode[StateType]):
65
65
  string_outputs.append(json.dumps(output.value, indent=4))
66
66
  elif output.type == "FUNCTION_CALL":
67
67
  string_outputs.append(output.value.model_dump_json(indent=4))
68
+ elif output.type == "THINKING":
69
+ if output.value.type == "STRING":
70
+ string_outputs.append(output.value.value)
68
71
  else:
69
72
  string_outputs.append(output.value.message)
70
73
 
@@ -0,0 +1,3 @@
1
+ from vellum.workflows.nodes.displayable.tool_calling_node.node import ToolCallingNode
2
+
3
+ __all__ = ["ToolCallingNode"]
@@ -1,16 +1,13 @@
1
- from collections.abc import Sequence
2
- from typing import Any, ClassVar, Dict, List, Optional, cast
1
+ from typing import ClassVar, List, Optional
3
2
 
4
3
  from vellum import ChatMessage, PromptBlock
5
- from vellum.client.types.code_execution_package import CodeExecutionPackage
6
- from vellum.client.types.code_execution_runtime import CodeExecutionRuntime
7
4
  from vellum.workflows.context import execution_context, get_parent_context
8
5
  from vellum.workflows.errors.types import WorkflowErrorCode
9
6
  from vellum.workflows.exceptions import NodeException
10
7
  from vellum.workflows.graph.graph import Graph
11
8
  from vellum.workflows.inputs.base import BaseInputs
12
9
  from vellum.workflows.nodes.bases import BaseNode
13
- from vellum.workflows.nodes.experimental.tool_calling_node.utils import (
10
+ from vellum.workflows.nodes.displayable.tool_calling_node.utils import (
14
11
  create_function_node,
15
12
  create_tool_router_node,
16
13
  get_function_name,
@@ -19,7 +16,6 @@ from vellum.workflows.outputs.base import BaseOutputs
19
16
  from vellum.workflows.state.base import BaseState
20
17
  from vellum.workflows.state.context import WorkflowContext
21
18
  from vellum.workflows.types.core import EntityInputsInterface, Tool
22
- from vellum.workflows.workflows.base import BaseWorkflow
23
19
 
24
20
 
25
21
  class ToolCallingNode(BaseNode):
@@ -31,7 +27,6 @@ class ToolCallingNode(BaseNode):
31
27
  blocks: List[PromptBlock] - The prompt blocks to use (same format as InlinePromptNode)
32
28
  functions: List[Tool] - The functions that can be called
33
29
  prompt_inputs: Optional[EntityInputsInterface] - Mapping of input variable names to values
34
- function_configs: Optional[Dict[str, Dict[str, Any]]] - Mapping of function names to their configuration
35
30
  max_prompt_iterations: Optional[int] - Maximum number of prompt iterations before stopping
36
31
  """
37
32
 
@@ -39,7 +34,6 @@ class ToolCallingNode(BaseNode):
39
34
  blocks: ClassVar[List[PromptBlock]] = []
40
35
  functions: ClassVar[List[Tool]] = []
41
36
  prompt_inputs: ClassVar[Optional[EntityInputsInterface]] = None
42
- function_configs: ClassVar[Optional[Dict[str, Dict[str, Any]]]] = None
43
37
  max_prompt_iterations: ClassVar[Optional[int]] = 5
44
38
 
45
39
  class Outputs(BaseOutputs):
@@ -69,6 +63,8 @@ class ToolCallingNode(BaseNode):
69
63
  chat_history: List[ChatMessage] = []
70
64
  prompt_iterations: int = 0
71
65
 
66
+ from vellum.workflows.workflows.base import BaseWorkflow
67
+
72
68
  class ToolCallingWorkflow(BaseWorkflow[BaseInputs, ToolCallingState]):
73
69
  graph = self._graph
74
70
 
@@ -112,23 +108,10 @@ class ToolCallingNode(BaseNode):
112
108
  self._function_nodes = {}
113
109
  for function in self.functions:
114
110
  function_name = get_function_name(function)
115
- # Get configuration for this function
116
- config = {}
117
- if callable(function) and self.function_configs and function.__name__ in self.function_configs:
118
- config = self.function_configs[function.__name__]
119
-
120
- packages = config.get("packages", None)
121
- if packages is not None:
122
- packages = cast(Sequence[CodeExecutionPackage], packages)
123
-
124
- runtime_raw = config.get("runtime", "PYTHON_3_11_6")
125
- runtime = cast(CodeExecutionRuntime, runtime_raw)
126
111
 
127
112
  self._function_nodes[function_name] = create_function_node(
128
113
  function=function,
129
114
  tool_router_node=self.tool_router_node,
130
- packages=packages,
131
- runtime=runtime,
132
115
  )
133
116
 
134
117
  graph_set = set()
@@ -8,7 +8,7 @@ from vellum.client.types.string_chat_message_content import StringChatMessageCon
8
8
  from vellum.workflows import BaseWorkflow
9
9
  from vellum.workflows.inputs.base import BaseInputs
10
10
  from vellum.workflows.nodes.bases import BaseNode
11
- from vellum.workflows.nodes.experimental.tool_calling_node.utils import create_function_node, create_tool_router_node
11
+ from vellum.workflows.nodes.displayable.tool_calling_node.utils import create_function_node, create_tool_router_node
12
12
  from vellum.workflows.outputs.base import BaseOutputs
13
13
  from vellum.workflows.state.base import BaseState, StateMeta
14
14
  from vellum.workflows.state.context import WorkflowContext
@@ -1,7 +1,7 @@
1
1
  from vellum.workflows import BaseWorkflow
2
2
  from vellum.workflows.inputs.base import BaseInputs
3
3
  from vellum.workflows.nodes.bases import BaseNode
4
- from vellum.workflows.nodes.experimental.tool_calling_node.utils import get_function_name
4
+ from vellum.workflows.nodes.displayable.tool_calling_node.utils import get_function_name
5
5
  from vellum.workflows.outputs.base import BaseOutputs
6
6
  from vellum.workflows.state.base import BaseState
7
7
  from vellum.workflows.types.definition import DeploymentDefinition
@@ -1,14 +1,9 @@
1
- from collections.abc import Sequence
2
- import inspect
3
1
  import json
4
- import types
5
2
  from typing import Any, Iterator, List, Optional, Type, cast
6
3
 
7
4
  from pydash import snake_case
8
5
 
9
6
  from vellum import ChatMessage, PromptBlock
10
- from vellum.client.types.code_execution_package import CodeExecutionPackage
11
- from vellum.client.types.code_execution_runtime import CodeExecutionRuntime
12
7
  from vellum.client.types.function_call_chat_message_content import FunctionCallChatMessageContent
13
8
  from vellum.client.types.function_call_chat_message_content_value import FunctionCallChatMessageContentValue
14
9
  from vellum.client.types.string_chat_message_content import StringChatMessageContent
@@ -16,13 +11,11 @@ from vellum.client.types.variable_prompt_block import VariablePromptBlock
16
11
  from vellum.workflows.errors.types import WorkflowErrorCode
17
12
  from vellum.workflows.exceptions import NodeException
18
13
  from vellum.workflows.nodes.bases import BaseNode
19
- from vellum.workflows.nodes.displayable.code_execution_node.node import CodeExecutionNode
20
14
  from vellum.workflows.nodes.displayable.inline_prompt_node.node import InlinePromptNode
21
15
  from vellum.workflows.nodes.displayable.subworkflow_deployment_node.node import SubworkflowDeploymentNode
22
16
  from vellum.workflows.outputs.base import BaseOutput
23
17
  from vellum.workflows.ports.port import Port
24
18
  from vellum.workflows.references.lazy import LazyReference
25
- from vellum.workflows.state.base import BaseState
26
19
  from vellum.workflows.state.context import WorkflowContext
27
20
  from vellum.workflows.state.encoder import DefaultStateEncoder
28
21
  from vellum.workflows.types.core import EntityInputsInterface, MergeBehavior, Tool
@@ -141,19 +134,16 @@ def create_tool_router_node(
141
134
  def create_function_node(
142
135
  function: Tool,
143
136
  tool_router_node: Type[ToolRouterNode],
144
- packages: Optional[Sequence[CodeExecutionPackage]] = None,
145
- runtime: CodeExecutionRuntime = "PYTHON_3_11_6",
146
137
  ) -> Type[FunctionNode]:
147
138
  """
148
139
  Create a FunctionNode class for a given function.
149
140
 
150
141
  For workflow functions: BaseNode
151
- For regular functions: CodeExecutionNode with embedded function
142
+ For regular functions: BaseNode with direct function call
143
+
152
144
  Args:
153
145
  function: The function to create a node for
154
146
  tool_router_node: The tool router node class
155
- packages: Optional list of packages to install for code execution (only used for regular functions)
156
- runtime: The runtime to use for code execution (default: "PYTHON_3_11_6")
157
147
  """
158
148
  if isinstance(function, DeploymentDefinition):
159
149
  deployment = function.deployment_id or function.deployment_name
@@ -250,24 +240,8 @@ def create_function_node(
250
240
  },
251
241
  )
252
242
  else:
253
- # For regular functions, use CodeExecutionNode approach
254
- # function tool must be put in another file (no need to have the same name)
255
- source_path = inspect.getmodule(function)
256
- if source_path is not None:
257
- function_source = inspect.getsource(source_path)
258
- else:
259
- function_source = f"<source code not available for {function.__name__}>"
260
- function_name = function.__name__
261
-
262
- code = f'''
263
- {function_source}
264
-
265
- def main(arguments):
266
- """Main function that calls the original function with the provided arguments."""
267
- return {function_name}(**arguments)
268
- '''
269
-
270
- def execute_code_execution_function(self) -> BaseNode.Outputs:
243
+ # For regular functions, call them directly
244
+ def execute_regular_function(self) -> BaseNode.Outputs:
271
245
  # Get the function call from the tool router output
272
246
  function_call_output = self.state.meta.node_outputs.get(tool_router_node.Outputs.results)
273
247
  if function_call_output and len(function_call_output) > 0:
@@ -276,42 +250,33 @@ def main(arguments):
276
250
  else:
277
251
  arguments = {}
278
252
 
279
- self.code_inputs = {"arguments": arguments}
280
-
281
- outputs = base_class.run(self)
253
+ # Call the function directly
254
+ try:
255
+ result = function(**arguments)
256
+ except Exception as e:
257
+ raise NodeException(
258
+ message=f"Error executing function '{function.__name__}': {str(e)}",
259
+ code=WorkflowErrorCode.NODE_EXECUTION,
260
+ )
282
261
 
262
+ # Add the result to the chat history
283
263
  self.state.chat_history.append(
284
264
  ChatMessage(
285
265
  role="FUNCTION",
286
- content=StringChatMessageContent(value=json.dumps(outputs.result, cls=DefaultStateEncoder)),
266
+ content=StringChatMessageContent(value=json.dumps(result, cls=DefaultStateEncoder)),
287
267
  )
288
268
  )
289
269
 
290
270
  return self.Outputs()
291
271
 
292
- # Create the properly typed base class with explicit type annotation
293
- def get_function_output_type() -> Type:
294
- return function.__annotations__.get("return", Any)
295
-
296
- output_type = get_function_output_type()
297
-
298
- base_class: Type[CodeExecutionNode] = CodeExecutionNode[BaseState, output_type] # type: ignore[valid-type]
299
-
300
- # Create the class with basic attributes
301
- node = types.new_class(
302
- f"CodeExecutionNode_{function.__name__}",
303
- (base_class,),
304
- {},
305
- lambda ns: ns.update(
306
- {
307
- "code": code,
308
- "code_inputs": {}, # No inputs needed since we handle function call extraction in run()
309
- "run": execute_code_execution_function,
310
- "runtime": runtime,
311
- "packages": packages,
312
- "__module__": __name__,
313
- }
314
- ),
272
+ # Create BaseNode for regular functions
273
+ node = type(
274
+ f"FunctionNode_{function.__name__}",
275
+ (FunctionNode,),
276
+ {
277
+ "run": execute_regular_function,
278
+ "__module__": __name__,
279
+ },
315
280
  )
316
281
 
317
282
  return node
@@ -1,3 +1,3 @@
1
- from .tool_calling_node import ToolCallingNode
1
+ from ..displayable.tool_calling_node import ToolCallingNode
2
2
 
3
3
  __all__ = ["ToolCallingNode"]
@@ -1,3 +1,3 @@
1
- from vellum.workflows.nodes.experimental.tool_calling_node.node import ToolCallingNode
1
+ from vellum.workflows.nodes.displayable.tool_calling_node import ToolCallingNode
2
2
 
3
3
  __all__ = ["ToolCallingNode"]
@@ -68,10 +68,10 @@ class DefaultStateEncoder(JSONEncoder):
68
68
  function_definition = compile_function_definition(obj)
69
69
  source_path = inspect.getsourcefile(obj)
70
70
  if source_path is not None:
71
- with open(source_path, "r") as f:
71
+ with open(source_path) as f:
72
72
  source_code = f.read()
73
73
  else:
74
- source_code = f"<source code not available for {obj.__name__}>"
74
+ source_code = f"# Error: Source code not available for {obj.__name__}"
75
75
 
76
76
  return {
77
77
  "type": "CODE_EXECUTION",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vellum-ai
3
- Version: 0.14.81
3
+ Version: 0.14.83
4
4
  Summary:
5
5
  License: MIT
6
6
  Requires-Python: >=3.9,<4.0