diff --git a/src/backend/langflow/interface/custom/utils.py b/src/backend/langflow/interface/custom/utils.py index 266a044f5..68951f3f8 100644 --- a/src/backend/langflow/interface/custom/utils.py +++ b/src/backend/langflow/interface/custom/utils.py @@ -20,6 +20,7 @@ from langflow.interface.custom.directory_reader.utils import ( merge_nested_dicts_with_renaming, ) from langflow.interface.custom.eval import eval_custom_component_code +from langflow.schema import dotdict from langflow.template.field.base import TemplateField from langflow.template.frontend_node.custom_components import ( CustomComponentFrontendNode, @@ -245,7 +246,7 @@ def add_extra_fields(frontend_node, field_config, function_args): def get_field_dict(field: Union[TemplateField, dict]): """Get the field dictionary from a TemplateField or a dict""" if isinstance(field, TemplateField): - return field.model_dump(by_alias=True, exclude_none=True) + return dotdict(field.model_dump(by_alias=True, exclude_none=True)) return field @@ -284,6 +285,7 @@ def run_build_config( # Allow user to build TemplateField as well # as a dict with the same keys as TemplateField field_dict = get_field_dict(field) + build_config[field_name] = field_dict # This has to be done to set refresh if options or value are callable if update_field is not None and field_name != update_field: build_config = update_field_dict( @@ -320,7 +322,11 @@ def run_build_config( return build_config, custom_instance except Exception as exc: + logger.error(f"Error while building field config: {str(exc)}") + if hasattr(exc, "detail") and "traceback" in exc.detail: + logger.error(exc.detail["traceback"]) + raise exc @@ -345,6 +351,7 @@ def build_frontend_node(template_config): def add_code_field(frontend_node: CustomComponentFrontendNode, raw_code, field_config): + code_field = TemplateField( dynamic=True, required=True, @@ -353,7 +360,7 @@ def add_code_field(frontend_node: CustomComponentFrontendNode, raw_code, field_c value=raw_code, password=False, name="code", - advanced=field_config.pop("advanced", False), + advanced=True, field_type="code", is_list=False, ) @@ -404,7 +411,7 @@ def build_custom_component_template( status_code=400, detail={ "error": ( - "Invalid type convertion. Please check your code and try again." + f"Something went wrong while building the custom component. Hints: {str(exc)}" ), "traceback": traceback.format_exc(), }, @@ -415,7 +422,6 @@ def create_component_template(component): """Create a template for a component.""" component_code = component["code"] component_output_types = component["output_types"] - # remove component_extractor = CustomComponent(code=component_code) @@ -431,9 +437,7 @@ def build_custom_components(components_paths: List[str]): if not components_paths: return {} - logger.info( - f"Building custom components from {components_paths}" - ) + logger.info(f"Building custom components from {components_paths}") custom_components_from_file = {} processed_paths = set() for path in components_paths: @@ -467,9 +471,11 @@ def update_field_dict( if "refresh" in field_dict: if call: try: + dd_build_config = dotdict(build_config) custom_component_instance.update_build_config( - build_config, update_field, update_field_value + dd_build_config, update_field, update_field_value ) + build_config = dd_build_config except Exception as exc: logger.error(f"Error while running update_build_config: {str(exc)}") raise UpdateBuildConfigError( @@ -483,8 +489,10 @@ def update_field_dict( return build_config -def sanitize_field_config(field_config: Dict): +def sanitize_field_config(field_config: Union[Dict, TemplateField]): # If any of the already existing keys are in field_config, remove them + if isinstance(field_config, TemplateField): + field_config = field_config.to_dict() for key in [ "name", "field_type", diff --git a/src/backend/langflow/schema/schema.py b/src/backend/langflow/schema/schema.py index 1b3e6b10e..077c20cf5 100644 --- a/src/backend/langflow/schema/schema.py +++ b/src/backend/langflow/schema/schema.py @@ -1,6 +1,6 @@ import copy -from langchain_core.documents import Document # Assumed import +from langchain_core.documents import Document from pydantic import BaseModel