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.
- vellum/__init__.py +10 -0
- vellum/client/README.md +1 -9
- vellum/client/__init__.py +44 -24
- vellum/client/core/client_wrapper.py +2 -1
- vellum/client/core/http_client.py +0 -2
- vellum/client/core/jsonable_encoder.py +0 -1
- vellum/client/core/pydantic_utilities.py +1 -3
- vellum/client/core/serialization.py +1 -2
- vellum/client/reference.md +8 -0
- vellum/client/resources/ad_hoc/client.py +20 -12
- vellum/client/resources/deployments/client.py +6 -2
- vellum/client/resources/documents/client.py +10 -0
- vellum/client/types/__init__.py +10 -0
- vellum/client/types/container_image_build_config.py +1 -0
- vellum/client/types/document_read.py +5 -0
- vellum/client/types/execution_thinking_vellum_value.py +31 -0
- vellum/client/types/execution_vellum_value.py +2 -0
- vellum/client/types/google_vertex_ai_vectorizer_gemini_embedding_001.py +21 -0
- vellum/client/types/google_vertex_ai_vectorizer_gemini_embedding_001_request.py +21 -0
- vellum/client/types/indexing_config_vectorizer.py +2 -0
- vellum/client/types/indexing_config_vectorizer_request.py +2 -0
- vellum/client/types/prompt_output.py +4 -1
- vellum/client/types/thinking_vellum_value.py +25 -0
- vellum/client/types/thinking_vellum_value_request.py +25 -0
- vellum/client/types/vellum_value.py +2 -0
- vellum/client/types/vellum_value_request.py +2 -0
- vellum/client/types/vellum_variable_type.py +1 -0
- vellum/client/types/workflow_sandbox_example.py +2 -0
- vellum/types/execution_thinking_vellum_value.py +3 -0
- vellum/types/google_vertex_ai_vectorizer_gemini_embedding_001.py +3 -0
- vellum/types/google_vertex_ai_vectorizer_gemini_embedding_001_request.py +3 -0
- vellum/types/thinking_vellum_value.py +3 -0
- vellum/types/thinking_vellum_value_request.py +3 -0
- vellum/workflows/nodes/displayable/__init__.py +2 -0
- vellum/workflows/nodes/displayable/inline_prompt_node/node.py +3 -0
- vellum/workflows/nodes/displayable/prompt_deployment_node/node.py +3 -0
- vellum/workflows/nodes/displayable/tool_calling_node/__init__.py +3 -0
- vellum/workflows/nodes/{experimental → displayable}/tool_calling_node/node.py +4 -21
- vellum/workflows/nodes/{experimental → displayable}/tool_calling_node/tests/test_node.py +1 -1
- vellum/workflows/nodes/{experimental → displayable}/tool_calling_node/tests/test_utils.py +1 -1
- vellum/workflows/nodes/{experimental → displayable}/tool_calling_node/utils.py +22 -57
- vellum/workflows/nodes/experimental/__init__.py +1 -1
- vellum/workflows/nodes/experimental/tool_calling_node/__init__.py +1 -1
- vellum/workflows/state/encoder.py +2 -2
- {vellum_ai-0.14.81.dist-info → vellum_ai-0.14.83.dist-info}/METADATA +1 -1
- {vellum_ai-0.14.81.dist-info → vellum_ai-0.14.83.dist-info}/RECORD +55 -44
- vellum_ee/workflows/display/nodes/vellum/tests/test_tool_calling_node.py +1 -104
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_inline_workflow_serialization.py +1 -6
- vellum_ee/workflows/display/tests/workflow_serialization/test_basic_tool_calling_node_serialization.py +1 -17
- vellum_ee/workflows/display/workflows/base_workflow_display.py +10 -5
- vellum_ee/workflows/tests/test_serialize_module.py +1 -1
- /vellum/workflows/nodes/{experimental → displayable}/tool_calling_node/tests/__init__.py +0 -0
- {vellum_ai-0.14.81.dist-info → vellum_ai-0.14.83.dist-info}/LICENSE +0 -0
- {vellum_ai-0.14.81.dist-info → vellum_ai-0.14.83.dist-info}/WHEEL +0 -0
- {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[
|
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
|
]
|
@@ -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
|
@@ -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
|
|
@@ -1,16 +1,13 @@
|
|
1
|
-
from
|
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.
|
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.
|
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.
|
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:
|
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,
|
254
|
-
|
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
|
-
|
280
|
-
|
281
|
-
|
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(
|
266
|
+
content=StringChatMessageContent(value=json.dumps(result, cls=DefaultStateEncoder)),
|
287
267
|
)
|
288
268
|
)
|
289
269
|
|
290
270
|
return self.Outputs()
|
291
271
|
|
292
|
-
# Create
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
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
|
@@ -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
|
71
|
+
with open(source_path) as f:
|
72
72
|
source_code = f.read()
|
73
73
|
else:
|
74
|
-
source_code = f"
|
74
|
+
source_code = f"# Error: Source code not available for {obj.__name__}"
|
75
75
|
|
76
76
|
return {
|
77
77
|
"type": "CODE_EXECUTION",
|