🐛 fix(base.py): import UtilitiesFrontendNode from the correct module
✨ feat(base.py): add support for SQLDatabase utility and filter utilities according to settings.utilities 🎨 style(frontend_node/base.py): add display_name to fields 🎨 style(frontend_node/utilities.py): format field values and types The import statement for UtilitiesFrontendNode was incorrect, causing an import error. The import statement was corrected to import from the correct module. Support for SQLDatabase utility was added to the type_to_loader_dict dictionary. The dictionary is now filtered according to the settings.utilities list. The display_name attribute was added to fields in the FrontendNode class to improve the readability of the frontend. The format_field method in the UtilitiesFrontendNode class was updated to format field values and types. The method now converts field.field_type to a list if it is a Literal type and formats field.value if it is a dictionary.
This commit is contained in:
parent
7da8c0ef92
commit
cc785af652
3 changed files with 57 additions and 10 deletions
|
|
@ -1,26 +1,53 @@
|
|||
from typing import Dict, List, Optional
|
||||
from typing import Dict, List, Optional, Type
|
||||
|
||||
from langflow.custom.customs import get_custom_nodes
|
||||
from langflow.interface.base import LangChainTypeCreator
|
||||
from langflow.interface.custom_lists import utility_type_to_cls_dict
|
||||
from langflow.interface.importing.utils import import_class
|
||||
from langflow.settings import settings
|
||||
from langflow.template.frontend_node.utilities import UtilitiesFrontendNode
|
||||
from langflow.utils.logger import logger
|
||||
from langflow.utils.util import build_template_from_class
|
||||
|
||||
from langchain import utilities, SQLDatabase
|
||||
|
||||
|
||||
class UtilityCreator(LangChainTypeCreator):
|
||||
type_name: str = "utilities"
|
||||
|
||||
@property
|
||||
def frontend_node_class(self) -> Type[UtilitiesFrontendNode]:
|
||||
return UtilitiesFrontendNode
|
||||
|
||||
@property
|
||||
def type_to_loader_dict(self) -> Dict:
|
||||
return utility_type_to_cls_dict
|
||||
"""
|
||||
Returns a dictionary mapping utility names to their corresponding loader classes.
|
||||
If the dictionary has not been created yet, it is created by importing all utility classes
|
||||
from the langchain.chains module and filtering them according to the settings.utilities list.
|
||||
"""
|
||||
if self.type_dict is None:
|
||||
self.type_dict = {
|
||||
utility_name: import_class(f"langchain.utilities.{utility_name}")
|
||||
for utility_name in utilities.__all__
|
||||
}
|
||||
self.type_dict["SQLDatabase"] = SQLDatabase
|
||||
# Filter according to settings.utilities
|
||||
self.type_dict = {
|
||||
name: utility
|
||||
for name, utility in self.type_dict.items()
|
||||
if name in settings.utilities or settings.dev
|
||||
}
|
||||
|
||||
return self.type_dict
|
||||
|
||||
def get_signature(self, name: str) -> Optional[Dict]:
|
||||
"""Get the signature of a utility."""
|
||||
try:
|
||||
if name in get_custom_nodes(self.type_name).keys():
|
||||
return get_custom_nodes(self.type_name)[name]
|
||||
return build_template_from_class(name, utility_type_to_cls_dict)
|
||||
custom_nodes = get_custom_nodes(self.type_name)
|
||||
if name in custom_nodes.keys():
|
||||
return custom_nodes[name]
|
||||
return build_template_from_class(name, self.type_to_loader_dict)
|
||||
except ValueError as exc:
|
||||
raise ValueError(f"Utility {name} not found") from exc
|
||||
|
||||
|
|
@ -29,11 +56,7 @@ class UtilityCreator(LangChainTypeCreator):
|
|||
return None
|
||||
|
||||
def to_list(self) -> List[str]:
|
||||
return [
|
||||
utility.__name__
|
||||
for utility in self.type_to_loader_dict.values()
|
||||
if utility.__name__ in settings.utilities or settings.dev
|
||||
]
|
||||
return list(self.type_to_loader_dict.keys())
|
||||
|
||||
|
||||
utility_creator = UtilityCreator()
|
||||
|
|
|
|||
|
|
@ -143,6 +143,9 @@ class FrontendNode(BaseModel):
|
|||
field.required = False
|
||||
field.advanced = False
|
||||
|
||||
field.display_name = key.replace("_", " ").title()
|
||||
field.display_name = field.display_name.replace("Api", "API")
|
||||
|
||||
@staticmethod
|
||||
def should_show_field(key: str, required: bool) -> bool:
|
||||
"""Determines whether the field should be shown."""
|
||||
|
|
|
|||
21
src/backend/langflow/template/frontend_node/utilities.py
Normal file
21
src/backend/langflow/template/frontend_node/utilities.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import json
|
||||
from typing import Optional
|
||||
|
||||
from langflow.template.field.base import TemplateField
|
||||
from langflow.template.frontend_node.base import FrontendNode
|
||||
|
||||
|
||||
class UtilitiesFrontendNode(FrontendNode):
|
||||
@staticmethod
|
||||
def format_field(field: TemplateField, name: Optional[str] = None) -> None:
|
||||
FrontendNode.format_field(field, name)
|
||||
# field.field_type could be "Literal['news', 'search', 'places', 'images']
|
||||
# we need to convert it to a list
|
||||
if "Literal" in field.field_type:
|
||||
field.options = eval(field.field_type.replace("Literal", ""))
|
||||
field.is_list = True
|
||||
field.field_type = "str"
|
||||
|
||||
if isinstance(field.value, dict):
|
||||
field.field_type = "code"
|
||||
field.value = json.dumps(field.value, indent=4)
|
||||
Loading…
Add table
Add a link
Reference in a new issue