feat(retrievers): add base retriever class and frontend node class

🐛 fix(util.py): handle non-string types in format_dict function
The base retriever class is added to provide a common interface for all retrievers in the language chain. The frontend node class for retrievers is also added to handle the formatting of fields specific to retrievers.

In the util.py file, a fix is made to handle non-string types in the format_dict function. Previously, if the type of a field was not a string, an error would occur. This fix ensures that the type is converted to a string before further processing.
This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-06-29 09:56:59 -03:00
commit 894fd16e8e
3 changed files with 67 additions and 0 deletions

View file

@ -0,0 +1,49 @@
from typing import Any, Dict, List, Optional, Type
from langchain import retrievers
from langflow.interface.base import LangChainTypeCreator
from langflow.interface.importing.utils import import_class
from langflow.settings import settings
from langflow.template.frontend_node.retrievers import RetrieverFrontendNode
from langflow.utils.logger import logger
from langflow.utils.util import build_template_from_method
class RetrieverCreator(LangChainTypeCreator):
type_name: str = "retrievers"
@property
def frontend_node_class(self) -> Type[RetrieverFrontendNode]:
return RetrieverFrontendNode
@property
def type_to_loader_dict(self) -> Dict:
if self.type_dict is None:
self.type_dict: dict[str, Any] = {
retriever_name: import_class(f"langchain.retrievers.{retriever_name}")
for retriever_name in retrievers.__all__
}
return self.type_dict
def get_signature(self, name: str) -> Optional[Dict]:
"""Get the signature of an embedding."""
try:
return build_template_from_method(
name, type_to_cls_dict=self.type_to_loader_dict, method_name="from_llm"
)
except ValueError as exc:
raise ValueError(f"Retriever {name} not found") from exc
except AttributeError as exc:
logger.error(f"Retriever {name} not loaded: {exc}")
return None
def to_list(self) -> List[str]:
return [
retriever
for retriever in self.type_to_loader_dict.keys()
if retriever in settings.retrievers or settings.dev
]
retriever_creator = RetrieverCreator()

View file

@ -0,0 +1,15 @@
from typing import Optional
from langflow.template.field.base import TemplateField
from langflow.template.frontend_node.base import FrontendNode
class RetrieverFrontendNode(FrontendNode):
@staticmethod
def format_field(field: TemplateField, name: Optional[str] = None) -> None:
FrontendNode.format_field(field, name)
# Define common field attributes
field.show = True
if field.name == "parser_key":
field.display_name = "Parser Key"
field.password = False

View file

@ -233,6 +233,9 @@ def format_dict(d, name: Optional[str] = None):
_type = value["type"]
if not isinstance(_type, str):
_type = _type.__name__
# Remove 'Optional' wrapper
if "Optional" in _type:
_type = _type.replace("Optional[", "")[:-1]