From 024cd3398a9d5a0baecf8370eb44bb4d51865be4 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 6 Jul 2023 23:56:04 -0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20fix(types.py):=20import=20correc?= =?UTF-8?q?t=20module=20for=20custom=20component=20creator=20=F0=9F=94=A7?= =?UTF-8?q?=20fix(types.py):=20fix=20import=20for=20CustomComponent=20clas?= =?UTF-8?q?s=20=F0=9F=94=A7=20fix(types.py):=20remove=20unused=20imports?= =?UTF-8?q?=20=F0=9F=94=A7=20fix(types.py):=20fix=20function=20signature?= =?UTF-8?q?=20for=20add=5Fnew=5Fcustom=5Ffield=20=F0=9F=94=A7=20fix(types.?= =?UTF-8?q?py):=20fix=20function=20signature=20for=20build=5Flangchain=5Ft?= =?UTF-8?q?emplate=5Fcustom=5Fcomponent=20=F0=9F=94=A7=20fix(types.py):=20?= =?UTF-8?q?fix=20return=20type=20validation=20and=20error=20handling=20in?= =?UTF-8?q?=20build=5Flangchain=5Ftemplate=5Fcustom=5Fcomponent=20?= =?UTF-8?q?=F0=9F=94=A7=20fix(types.py):=20fix=20appending=20base=20classe?= =?UTF-8?q?s=20to=20frontend=5Fnode=20in=20build=5Flangchain=5Ftemplate=5F?= =?UTF-8?q?custom=5Fcomponent=20=F0=9F=94=A7=20fix(types.py):=20fix=20retu?= =?UTF-8?q?rn=20statement=20in=20build=5Flangchain=5Ftemplate=5Fcustom=5Fc?= =?UTF-8?q?omponent=20The=20changes=20in=20this=20commit=20fix=20import=20?= =?UTF-8?q?statements,=20function=20signatures,=20and=20error=20handling?= =?UTF-8?q?=20in=20the=20types.py=20file.=20The=20correct=20module=20is=20?= =?UTF-8?q?now=20imported=20for=20the=20custom=20component=20creator.=20Th?= =?UTF-8?q?e=20import=20for=20the=20CustomComponent=20class=20is=20fixed.?= =?UTF-8?q?=20Unused=20imports=20are=20removed.=20The=20function=20signatu?= =?UTF-8?q?re=20for=20add=5Fnew=5Fcustom=5Ffield=20is=20fixed=20to=20inclu?= =?UTF-8?q?de=20the=20field=5Fconfig=20parameter.=20The=20function=20signa?= =?UTF-8?q?ture=20for=20build=5Flangchain=5Ftemplate=5Fcustom=5Fcomponent?= =?UTF-8?q?=20is=20fixed=20to=20include=20the=20field=5Fconfig=20parameter?= =?UTF-8?q?.=20The=20return=20type=20validation=20and=20error=20handling?= =?UTF-8?q?=20in=20build=5Flangchain=5Ftemplate=5Fcustom=5Fcomponent=20are?= =?UTF-8?q?=20fixed=20to=20handle=20invalid=20return=20types.=20The=20base?= =?UTF-8?q?=20classes=20are=20correctly=20appended=20to=20the=20frontend?= =?UTF-8?q?=5Fnode=20in=20build=5Flangchain=5Ftemplate=5Fcustom=5Fcomponen?= =?UTF-8?q?t.=20The=20return=20statement=20in=20build=5Flangchain=5Ftempla?= =?UTF-8?q?te=5Fcustom=5Fcomponent=20is=20fixed=20to=20return=20the=20fron?= =?UTF-8?q?tend=5Fnode.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/interface/types.py | 70 +++++++++++++++++-------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/src/backend/langflow/interface/types.py b/src/backend/langflow/interface/types.py index f331c3416..c91abcfbe 100644 --- a/src/backend/langflow/interface/types.py +++ b/src/backend/langflow/interface/types.py @@ -1,5 +1,6 @@ from langflow.interface.agents.base import agent_creator from langflow.interface.chains.base import chain_creator +from langflow.interface.custom.constants import LANGCHAIN_BASE_TYPES from langflow.interface.document_loaders.base import documentloader_creator from langflow.interface.embeddings.base import embedding_creator from langflow.interface.llms.base import llm_creator @@ -12,7 +13,8 @@ from langflow.interface.utilities.base import utility_creator from langflow.interface.vector_store.base import vectorstore_creator from langflow.interface.wrappers.base import wrapper_creator from langflow.interface.output_parsers.base import output_parser_creator -from langflow.interface.tools.custom import CustomComponent +from langflow.interface.custom.base import custom_component_creator +from langflow.interface.custom.custom import CustomComponent from langflow.template.field.base import TemplateField from langflow.template.frontend_node.tools import CustomComponentNode @@ -24,9 +26,6 @@ from fastapi import HTTPException import traceback # Used to get the base_classes list -from langchain.chains import ConversationChain # noqa: F401 -from langchain.llms.base import BaseLLM # noqa: F401 -from langchain.tools import Tool # noqa: F401 def get_type_list(): @@ -62,6 +61,7 @@ def build_langchain_types_dict(): # sourcery skip: dict-assign-update-to-union utility_creator, output_parser_creator, retriever_creator, + custom_component_creator, ] all_types = {} @@ -73,9 +73,16 @@ def build_langchain_types_dict(): # sourcery skip: dict-assign-update-to-union # TODO: Move to correct place -def add_new_custom_field(template, field_name: str, field_type: str): +def add_new_custom_field( + template, field_name: str, field_type: str, field_config: dict +): new_field = TemplateField( - name=field_name, field_type=field_type, show=True, required=True, advanced=False + name=field_name, + field_type=field_type, + show=True, + required=True, + advanced=False, + **field_config, ) template.get("template")[field_name] = new_field.to_dict() template.get("custom_fields")[field_name] = None @@ -108,28 +115,45 @@ def add_code_field(template, raw_code): def build_langchain_template_custom_component(extractor: CustomComponent): # Build base "CustomComponent" template - template = CustomComponentNode().to_dict().get(type(extractor).__name__) + frontend_node = CustomComponentNode().to_dict().get(type(extractor).__name__) - function_args, return_type = extractor.args_and_return_type + function_args, return_type, template_config = extractor.args_and_return_type + + if "display_name" in template_config and frontend_node is not None: + frontend_node["display_name"] = template_config["display_name"] raw_code = extractor.code + field_config = template_config.get("field_config", {}) + if function_args is not None: + # Add extra fields + for extra_field in function_args: + def_field = extra_field[0] + def_type = extra_field[1] - # Add extra fields - for extra_field in function_args: - def_field = extra_field[0] - def_type = extra_field[1] + if def_field != "self": + # TODO: Validate type - if is possible to render into frontend + if not def_type: + def_type = "str" + config = field_config.get(def_field, {}) + frontend_node = add_new_custom_field( + frontend_node, def_field, def_type, config + ) - if def_field != "self": - # TODO: Validate type - if is possible to render into frontend - if not def_type: - def_type = "str" - - template = add_new_custom_field(template, def_field, def_type) - - template = add_code_field(template, raw_code) + frontend_node = add_code_field(frontend_node, raw_code) # Get base classes from "return_type" and add to template.base_classes try: - return_type_instance = globals()[return_type] + if return_type not in LANGCHAIN_BASE_TYPES or return_type is None: + raise HTTPException( + status_code=400, + detail={ + "error": ( + "Invalid return type should be one of: " + f"{list(LANGCHAIN_BASE_TYPES.keys())}" + ), + "traceback": traceback.format_exc(), + }, + ) + return_type_instance = LANGCHAIN_BASE_TYPES.get(return_type) base_classes = get_base_classes(return_type_instance) except (KeyError, AttributeError) as err: raise HTTPException( @@ -138,9 +162,9 @@ def build_langchain_template_custom_component(extractor: CustomComponent): ) from err for base_class in base_classes: - template.get("base_classes").append(base_class) + frontend_node.get("base_classes").append(base_class) - return template + return frontend_node langchain_types_dict = build_langchain_types_dict()