🚀 feat(langflow): rename PythonFunction to PythonFunctionTool for better semantics
🚀 feat(langflow): add PythonFunctionToolNode to the frontend node tools 🚀 feat(langflow): add PythonFunctionTool to the custom tools 🚀 feat(langflow): add get_function to importing utils to get the function from code 🚀 feat(langflow): add func parameter to PythonFunctionTool to store the function 🚀 feat(langflow): add name and description parameters to PythonFunctionTool 🚀 feat(langflow): update instantiate_tool to use PythonFunctionTool instead of PythonFunction 🚀 feat(langflow): update constants to use PythonFunctionTool instead of PythonFunction 🚀 feat(langflow): update custom.py to use PythonFunctionTool instead of PythonFunction 🚀 feat(langflow): update loading.py to use get_function and PythonFunctionTool 🚀 feat(langflow): update utils.py to use get_function 🚀 feat(langflow): update test_custom_types.py to use get_function and PythonFunctionTool 🚀 feat(langflow): update test_graph.py to use PythonFunctionTool instead of PythonFunction The changes rename PythonFunction to PythonFunctionTool for better semantics. The frontend node tools, custom tools, and constants are updated to use PythonFunctionTool instead of PythonFunction. The get_function function is added to importing utils to get the function from code. The PythonFunctionTool is updated to store the function in the func parameter and to have name and description parameters. The instantiate_tool, loading.py, and utils.py are updated to use get_function and PythonFunctionTool. The test_custom_types.py and test_graph.py are updated to use PythonFunctionTool instead of PythonFunction.
This commit is contained in:
parent
dedbe3c906
commit
be09849081
10 changed files with 73 additions and 31 deletions
|
|
@ -79,7 +79,7 @@ tools:
|
|||
- Calculator
|
||||
- Serper Search
|
||||
- Tool
|
||||
- PythonFunction
|
||||
- PythonFunctionTool
|
||||
- JsonSpec
|
||||
- News API
|
||||
- TMDB API
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from langflow.template import frontend_node
|
|||
CUSTOM_NODES = {
|
||||
"prompts": {"ZeroShotPrompt": frontend_node.prompts.ZeroShotPromptNode()},
|
||||
"tools": {
|
||||
"PythonFunction": frontend_node.tools.PythonFunctionNode(),
|
||||
"PythonFunctionTool": frontend_node.tools.PythonFunctionToolNode(),
|
||||
"Tool": frontend_node.tools.ToolNode(),
|
||||
},
|
||||
"agents": {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from langchain.base_language import BaseLanguageModel
|
|||
from langchain.chains.base import Chain
|
||||
from langchain.chat_models.base import BaseChatModel
|
||||
from langchain.tools import BaseTool
|
||||
from langflow.utils import validate
|
||||
|
||||
|
||||
def import_module(module_path: str) -> Any:
|
||||
|
|
@ -147,3 +148,10 @@ def import_utility(utility: str) -> Any:
|
|||
if utility == "SQLDatabase":
|
||||
return import_class(f"langchain.sql_database.{utility}")
|
||||
return import_class(f"langchain.utilities.{utility}")
|
||||
|
||||
|
||||
def get_function(code):
|
||||
"""Get the function"""
|
||||
function_name = validate.extract_function_name(code)
|
||||
|
||||
return validate.create_function(code, function_name)
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ from langchain.llms.loading import load_llm_from_config
|
|||
from pydantic import ValidationError
|
||||
|
||||
from langflow.interface.agents.custom import CUSTOM_AGENTS
|
||||
from langflow.interface.importing.utils import import_by_type
|
||||
from langflow.interface.importing.utils import get_function, import_by_type
|
||||
from langflow.interface.run import fix_memory_inputs
|
||||
from langflow.interface.toolkits.base import toolkits_creator
|
||||
from langflow.interface.types import get_type_list
|
||||
from langflow.interface.utils import load_file_into_dict
|
||||
from langflow.utils import util, validate
|
||||
from langflow.utils import util
|
||||
|
||||
|
||||
def instantiate_class(node_type: str, base_type: str, params: Dict) -> Any:
|
||||
|
|
@ -99,11 +99,9 @@ def instantiate_tool(node_type, class_object, params):
|
|||
if node_type == "JsonSpec":
|
||||
params["dict_"] = load_file_into_dict(params.pop("path"))
|
||||
return class_object(**params)
|
||||
elif node_type == "PythonFunction":
|
||||
function_string = params["code"]
|
||||
if isinstance(function_string, str):
|
||||
return validate.eval_function(function_string)
|
||||
raise ValueError("Function should be a string")
|
||||
elif node_type == "PythonFunctionTool":
|
||||
params["func"] = get_function(params.get("code"))
|
||||
return class_object(**params)
|
||||
elif node_type.lower() == "tool":
|
||||
return class_object(**params)
|
||||
return class_object(**params)
|
||||
|
|
|
|||
|
|
@ -71,7 +71,8 @@ class ToolCreator(LangChainTypeCreator):
|
|||
|
||||
for tool, tool_fcn in ALL_TOOLS_NAMES.items():
|
||||
tool_params = get_tool_params(tool_fcn)
|
||||
tool_name = tool_params.get("name", tool)
|
||||
|
||||
tool_name = tool_params.get("name") or tool
|
||||
|
||||
if tool_name in settings.tools or settings.dev:
|
||||
if tool_name == "JsonSpec":
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ from langchain.agents.load_tools import (
|
|||
from langchain.tools.json.tool import JsonSpec
|
||||
|
||||
from langflow.interface.importing.utils import import_class
|
||||
from langflow.interface.tools.custom import PythonFunction
|
||||
from langflow.interface.tools.custom import PythonFunctionTool
|
||||
|
||||
FILE_TOOLS = {"JsonSpec": JsonSpec}
|
||||
CUSTOM_TOOLS = {"Tool": Tool, "PythonFunction": PythonFunction}
|
||||
CUSTOM_TOOLS = {"Tool": Tool, "PythonFunctionTool": PythonFunctionTool}
|
||||
|
||||
OTHER_TOOLS = {tool: import_class(f"langchain.tools.{tool}") for tool in tools.__all__}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
from typing import Callable, Optional
|
||||
from typing import Optional
|
||||
from langflow.interface.importing.utils import get_function
|
||||
|
||||
from pydantic import BaseModel, validator
|
||||
|
||||
from langflow.utils import validate
|
||||
from langchain.agents.tools import Tool
|
||||
|
||||
|
||||
class Function(BaseModel):
|
||||
code: str
|
||||
function: Optional[Callable] = None
|
||||
imports: Optional[str] = None
|
||||
|
||||
# Eval code and store the function
|
||||
|
|
@ -24,14 +25,17 @@ class Function(BaseModel):
|
|||
|
||||
return v
|
||||
|
||||
def get_function(self):
|
||||
"""Get the function"""
|
||||
function_name = validate.extract_function_name(self.code)
|
||||
|
||||
return validate.create_function(self.code, function_name)
|
||||
|
||||
|
||||
class PythonFunction(Function):
|
||||
class PythonFunctionTool(Function, Tool):
|
||||
"""Python function"""
|
||||
|
||||
name: str = "Custom Tool"
|
||||
description: str
|
||||
code: str
|
||||
|
||||
def ___init__(self, name: str, description: str, code: str):
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.code = code
|
||||
self.func = get_function(self.code)
|
||||
super().__init__(name=name, description=description, func=self.func)
|
||||
|
|
|
|||
|
|
@ -59,11 +59,33 @@ class ToolNode(FrontendNode):
|
|||
return super().to_dict()
|
||||
|
||||
|
||||
class PythonFunctionNode(FrontendNode):
|
||||
name: str = "PythonFunction"
|
||||
class PythonFunctionToolNode(FrontendNode):
|
||||
name: str = "PythonFunctionTool"
|
||||
template: Template = Template(
|
||||
type_name="python_function",
|
||||
type_name="PythonFunctionTool",
|
||||
fields=[
|
||||
TemplateField(
|
||||
field_type="str",
|
||||
required=True,
|
||||
placeholder="",
|
||||
is_list=False,
|
||||
show=True,
|
||||
multiline=False,
|
||||
value="",
|
||||
name="name",
|
||||
advanced=False,
|
||||
),
|
||||
TemplateField(
|
||||
field_type="str",
|
||||
required=True,
|
||||
placeholder="",
|
||||
is_list=False,
|
||||
show=True,
|
||||
multiline=False,
|
||||
value="",
|
||||
name="description",
|
||||
advanced=False,
|
||||
),
|
||||
TemplateField(
|
||||
field_type="code",
|
||||
required=True,
|
||||
|
|
@ -73,11 +95,11 @@ class PythonFunctionNode(FrontendNode):
|
|||
value=DEFAULT_PYTHON_FUNCTION,
|
||||
name="code",
|
||||
advanced=False,
|
||||
)
|
||||
),
|
||||
],
|
||||
)
|
||||
description: str = "Python function to be executed."
|
||||
base_classes: list[str] = ["function"]
|
||||
base_classes: list[str] = ["Tool"]
|
||||
|
||||
def to_dict(self):
|
||||
return super().to_dict()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue