feat: implemented file loading and toolkit

This commit is contained in:
Gabriel Almeida 2023-03-31 14:03:32 -03:00
commit fbca59d42c
2 changed files with 64 additions and 18 deletions

View file

@ -3,19 +3,22 @@
# - Defer prompts building to the last moment or when they have all the tools
# - Build each inner agent first, then build the outer agent
from copy import deepcopy
import types
from copy import deepcopy
from typing import Any, Dict, List
from langflow.interface.listing import ALL_TYPES_DICT
from langflow.graph.utils import load_dict
from langflow.interface import loading
from langflow.interface.listing import ALL_TYPES_DICT
from langflow.interface.tools.base import tool_creator
class Node:
def __init__(self, data: Dict):
def __init__(self, data: Dict, base_type: str | None = None) -> None:
self.id: str = data["id"]
self._data = data
self.edges: List[Edge] = []
self.base_type: str | None = base_type
self._parse_data()
self._built_object = None
self._built = False
@ -44,6 +47,11 @@ class Node:
self.node_type = (
self.data["type"] if "Tool" not in self.output else template_dict["_type"]
)
if self.base_type is None:
for base_type, value in ALL_TYPES_DICT.items():
if self.node_type in value:
self.base_type = base_type
break
def _build_params(self):
# Some params are required, some are optional
@ -71,7 +79,18 @@ class Node:
continue
# If the type is not transformable to a python base class
# then we need to get the edge that connects to this node
if value["type"] not in ["str", "bool", "code"]:
if value["type"] == "file":
# Load the type in value.get('suffixes') using
# what is inside value.get('content')
# value.get('value') is the file name
type_to_load = value.get("suffixes")
file_name = value.get("value")
content = value.get("content")
# Now
loaded_dict = load_dict(file_name, content, type_to_load)
params[key] = loaded_dict
elif value["type"] not in ["str", "bool", "code", "int", "float"]:
# Get the edge that connects to this node
edge = next(
(
@ -138,17 +157,15 @@ class Node:
# Get the class from LANGCHAIN_TYPES_DICT
# and instantiate it with the params
# and return the instance
for base_type, value in ALL_TYPES_DICT.items():
if base_type == "tools":
value = tool_creator.type_to_loader_dict
if self.node_type in value:
self._built_object = loading.instantiate_class(
node_type=self.node_type,
base_type=base_type,
params=self.params,
)
break
try:
self._built_object = loading.instantiate_class(
node_type=self.node_type,
base_type=self.base_type,
params=self.params,
)
except Exception as exc:
raise ValueError(f"Error building node {self.node_type}") from exc
if self._built_object is None:
raise ValueError(f"Node type {self.node_type} not found")

View file

@ -1,12 +1,28 @@
from langflow.interface.base import LangChainTypeCreator
from langflow.utils.util import build_template_from_class
from typing import Dict, List
from typing import Callable, Dict, List
from langchain.agents import agent_toolkits
from langflow.interface.importing.utils import import_class
from langflow.interface.base import LangChainTypeCreator
from langflow.interface.importing.utils import import_class, import_module
from langflow.utils.util import build_template_from_class
class ToolkitCreator(LangChainTypeCreator):
type_name: str = "toolkits"
all_types: List[str] = agent_toolkits.__all__
create_functions: Dict = {
"JsonToolkit": [],
"SQLDatabaseToolkit": [],
"OpenAPIToolkit": ["create_openapi_agent"],
"VectorStoreToolkit": [
"create_vectorstore_agent",
"create_vectorstore_router_agent",
"VectorStoreInfo",
],
"ZapierToolkit": [],
"PandasToolkit": ["create_pandas_dataframe_agent"],
"CSVToolkit": ["create_csv_agent"],
}
@property
def type_to_loader_dict(self) -> Dict:
@ -19,6 +35,7 @@ class ToolkitCreator(LangChainTypeCreator):
for toolkit_name in agent_toolkits.__all__
if not toolkit_name.islower()
}
return self.type_dict
def get_signature(self, name: str) -> Dict | None:
@ -30,5 +47,17 @@ class ToolkitCreator(LangChainTypeCreator):
def to_list(self) -> List[str]:
return list(self.type_to_loader_dict.keys())
def get_create_function(self, name: str) -> Callable | None:
if loader_name := self.create_functions.get(name, None):
# import loader
return import_module(
f"from langchain.agents.agent_toolkits import {loader_name[0]}"
)
return None
def has_create_function(self, name: str) -> bool:
# check if the function list is not empty
return bool(self.create_functions.get(name, None))
toolkits_creator = ToolkitCreator()