From 59126fa01a7d5c68309f0c7f5f42a8fc5f88955b Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Thu, 30 May 2024 17:55:02 -0300 Subject: [PATCH] refactor: rename InputField to Input --- .../components/experimental/SubFlow.py | 6 ++-- .../components/helpers/CreateRecord.py | 4 +-- .../base/langflow/components/inputs/Prompt.py | 6 ++-- src/backend/base/langflow/custom/utils.py | 20 ++++++------ .../base/langflow/field_typing/__init__.py | 8 ++--- .../Basic Prompting (Hello, world!).json | 2 +- .../Langflow Blog Writter.json | 2 +- .../Langflow Document QA.json | 2 +- .../Langflow Memory Conversation.json | 2 +- .../Langflow Prompt Chaining.json | 4 +-- .../VectorStore-RAG-Flows.json | 2 +- .../base/langflow/template/field/base.py | 6 ++-- .../base/langflow/template/field/prompt.py | 4 +-- .../langflow/template/frontend_node/base.py | 28 ++++++++-------- .../frontend_node/custom_components.py | 4 +-- .../template/frontend_node/formatter/base.py | 4 +-- .../formatter/field_formatters.py | 32 +++++++++---------- .../base/langflow/template/template/base.py | 12 +++---- tests/data/component_with_templatefield.py | 4 +-- tests/test_frontend_nodes.py | 12 +++---- 20 files changed, 82 insertions(+), 82 deletions(-) diff --git a/src/backend/base/langflow/components/experimental/SubFlow.py b/src/backend/base/langflow/components/experimental/SubFlow.py index 86deaf8ba..86dd336bf 100644 --- a/src/backend/base/langflow/components/experimental/SubFlow.py +++ b/src/backend/base/langflow/components/experimental/SubFlow.py @@ -10,7 +10,7 @@ from langflow.graph.vertex.base import Vertex from langflow.helpers.flow import get_flow_inputs from langflow.schema import Record from langflow.schema.dotdict import dotdict -from langflow.template.field.base import InputField +from langflow.template.field.base import Input class SubFlowComponent(CustomComponent): @@ -54,9 +54,9 @@ class SubFlowComponent(CustomComponent): return build_config def add_inputs_to_build_config(self, inputs: List[Vertex], build_config: dotdict): - new_fields: list[InputField] = [] + new_fields: list[Input] = [] for vertex in inputs: - field = InputField( + field = Input( display_name=vertex.display_name, name=vertex.id, info=vertex.description, diff --git a/src/backend/base/langflow/components/helpers/CreateRecord.py b/src/backend/base/langflow/components/helpers/CreateRecord.py index e37569b6b..d466f5c26 100644 --- a/src/backend/base/langflow/components/helpers/CreateRecord.py +++ b/src/backend/base/langflow/components/helpers/CreateRecord.py @@ -4,7 +4,7 @@ from langflow.custom import CustomComponent from langflow.field_typing.range_spec import RangeSpec from langflow.schema import Record from langflow.schema.dotdict import dotdict -from langflow.template.field.base import InputField +from langflow.template.field.base import Input class CreateRecordComponent(CustomComponent): @@ -35,7 +35,7 @@ class CreateRecordComponent(CustomComponent): field = existing_fields[key] build_config[key] = field else: - field = InputField( + field = Input( display_name=f"Field {i}", name=key, info=f"Key for field {i}.", diff --git a/src/backend/base/langflow/components/inputs/Prompt.py b/src/backend/base/langflow/components/inputs/Prompt.py index b0f7930db..f14b9dbdd 100644 --- a/src/backend/base/langflow/components/inputs/Prompt.py +++ b/src/backend/base/langflow/components/inputs/Prompt.py @@ -1,7 +1,7 @@ from langchain_core.prompts import PromptTemplate from langflow.custom import CustomComponent -from langflow.field_typing import InputField, Prompt, Text +from langflow.field_typing import Input, Prompt, Text class PromptComponent(CustomComponent): @@ -11,8 +11,8 @@ class PromptComponent(CustomComponent): def build_config(self): return { - "template": InputField(display_name="Template"), - "code": InputField(advanced=True), + "template": Input(display_name="Template"), + "code": Input(advanced=True), } def build( diff --git a/src/backend/base/langflow/custom/utils.py b/src/backend/base/langflow/custom/utils.py index d2a769aea..2a941a418 100644 --- a/src/backend/base/langflow/custom/utils.py +++ b/src/backend/base/langflow/custom/utils.py @@ -22,7 +22,7 @@ from langflow.custom.eval import eval_custom_component_code from langflow.custom.schema import MissingDefault from langflow.field_typing.range_spec import RangeSpec from langflow.schema import dotdict -from langflow.template.field.base import InputField +from langflow.template.field.base import Input from langflow.template.frontend_node.custom_components import CustomComponentFrontendNode from langflow.utils import validate from langflow.utils.util import get_base_classes @@ -169,7 +169,7 @@ def add_new_custom_field( required = field_config.pop("required", field_required) placeholder = field_config.pop("placeholder", "") - new_field = InputField( + new_field = Input( name=field_name, field_type=field_type, value=field_value, @@ -231,9 +231,9 @@ def add_extra_fields(frontend_node, field_config, function_args): ) -def get_field_dict(field: Union[InputField, dict]): - """Get the field dictionary from a InputField or a dict""" - if isinstance(field, InputField): +def get_field_dict(field: Union[Input, dict]): + """Get the field dictionary from a Input or a dict""" + if isinstance(field, Input): return dotdict(field.model_dump(by_alias=True, exclude_none=True)) return field @@ -266,8 +266,8 @@ def run_build_config( build_config: Dict = custom_instance.build_config() for field_name, field in build_config.copy().items(): - # Allow user to build InputField as well - # as a dict with the same keys as InputField + # Allow user to build Input as well + # as a dict with the same keys as Input field_dict = get_field_dict(field) # Let's check if "rangeSpec" is a RangeSpec object if "rangeSpec" in field_dict and isinstance(field_dict["rangeSpec"], RangeSpec): @@ -305,7 +305,7 @@ def build_frontend_node(template_config): def add_code_field(frontend_node: CustomComponentFrontendNode, raw_code, field_config): - code_field = InputField( + code_field = Input( dynamic=True, required=True, placeholder="", @@ -429,9 +429,9 @@ def update_field_dict( return build_config -def sanitize_field_config(field_config: Union[Dict, InputField]): +def sanitize_field_config(field_config: Union[Dict, Input]): # If any of the already existing keys are in field_config, remove them - if isinstance(field_config, InputField): + if isinstance(field_config, Input): field_dict = field_config.to_dict() else: field_dict = field_config diff --git a/src/backend/base/langflow/field_typing/__init__.py b/src/backend/base/langflow/field_typing/__init__.py index d037aa371..7ae9c61a9 100644 --- a/src/backend/base/langflow/field_typing/__init__.py +++ b/src/backend/base/langflow/field_typing/__init__.py @@ -30,14 +30,14 @@ from .range_spec import RangeSpec def _import_template_field(): - from langflow.template.field.base import InputField + from langflow.template.field.base import Input - return InputField + return Input def __getattr__(name: str) -> Any: # This is to avoid circular imports - if name == "InputField": + if name == "Input": return _import_template_field() elif name == "RangeSpec": return RangeSpec @@ -73,6 +73,6 @@ __all__ = [ "ChatPromptTemplate", "Prompt", "RangeSpec", - "InputField", + "Input", "Code", ] diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json index 786eac776..2d6255562 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json @@ -20,7 +20,7 @@ "list": false, "show": true, "multiline": true, - "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import InputField, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": InputField(display_name=\"Template\"),\n \"code\": InputField(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", + "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Input, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", "fileTypes": [], "file_path": "", "password": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json index 9f4b98176..e68eed258 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json @@ -20,7 +20,7 @@ "list": false, "show": true, "multiline": true, - "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import InputField, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": InputField(display_name=\"Template\"),\n \"code\": InputField(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", + "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Input, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", "fileTypes": [], "file_path": "", "password": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json index c14d21d1a..3afd6f04f 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json @@ -20,7 +20,7 @@ "list": false, "show": true, "multiline": true, - "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import InputField, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": InputField(display_name=\"Template\"),\n \"code\": InputField(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", + "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Input, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", "fileTypes": [], "file_path": "", "password": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json index 50142c4a1..0b12d8d19 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json @@ -583,7 +583,7 @@ "list": false, "show": true, "multiline": true, - "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import InputField, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": InputField(display_name=\"Template\"),\n \"code\": InputField(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", + "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Input, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", "fileTypes": [], "file_path": "", "password": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json index e7cb1b021..43212bd61 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json @@ -20,7 +20,7 @@ "list": false, "show": true, "multiline": true, - "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import InputField, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": InputField(display_name=\"Template\"),\n \"code\": InputField(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", + "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Input, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", "fileTypes": [], "file_path": "", "password": false, @@ -140,7 +140,7 @@ "list": false, "show": true, "multiline": true, - "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import InputField, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": InputField(display_name=\"Template\"),\n \"code\": InputField(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", + "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Input, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", "fileTypes": [], "file_path": "", "password": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json b/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json index 4bbb1aab3..09b37d168 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json @@ -1106,7 +1106,7 @@ "list": false, "show": true, "multiline": true, - "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import InputField, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": InputField(display_name=\"Template\"),\n \"code\": InputField(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", + "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Input, Prompt, Text\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n", "fileTypes": [], "file_path": "", "password": false, diff --git a/src/backend/base/langflow/template/field/base.py b/src/backend/base/langflow/template/field/base.py index 3aa4c020d..0ba947a28 100644 --- a/src/backend/base/langflow/template/field/base.py +++ b/src/backend/base/langflow/template/field/base.py @@ -5,7 +5,7 @@ from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_valid from langflow.field_typing.range_spec import RangeSpec -class InputField(BaseModel): +class Input(BaseModel): model_config = ConfigDict() field_type: str = Field(default="str", serialization_alias="type") @@ -130,8 +130,8 @@ class InputField(BaseModel): ] -class OutputField(BaseModel): - types: list[str] = Field(default=[], serialization_alias="types") +class Output(BaseModel): + type: list[str] = Field(default=[], serialization_alias="types") """List of output types for the field.""" selected: Optional[str] = Field(default=None, serialization_alias="selected") diff --git a/src/backend/base/langflow/template/field/prompt.py b/src/backend/base/langflow/template/field/prompt.py index ecca72503..d03291ee4 100644 --- a/src/backend/base/langflow/template/field/prompt.py +++ b/src/backend/base/langflow/template/field/prompt.py @@ -1,9 +1,9 @@ from typing import Optional -from langflow.template.field.base import InputField +from langflow.template.field.base import Input -class DefaultPromptField(InputField): +class DefaultPromptField(Input): name: str display_name: Optional[str] = None field_type: str = "str" diff --git a/src/backend/base/langflow/template/frontend_node/base.py b/src/backend/base/langflow/template/frontend_node/base.py index 2d69922cf..2ac4acbab 100644 --- a/src/backend/base/langflow/template/frontend_node/base.py +++ b/src/backend/base/langflow/template/frontend_node/base.py @@ -4,7 +4,7 @@ from typing import ClassVar, Dict, List, Optional, Union from pydantic import BaseModel, Field, field_serializer, model_serializer -from langflow.template.field.base import InputField, OutputField +from langflow.template.field.base import Input, Output from langflow.template.frontend_node.constants import FORCE_SHOW_FIELDS from langflow.template.frontend_node.formatter import field_formatters from langflow.template.template.base import Template @@ -30,7 +30,7 @@ class FieldFormatters(BaseModel): "model_fields": field_formatters.ModelSpecificFieldFormatter(), } - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: for key, formatter in self.base_formatters.items(): formatter.format(field, name) @@ -77,7 +77,7 @@ class FrontendNode(BaseModel): """List of conditional paths for the frontend node.""" frozen: bool = False """Whether the frontend node is frozen.""" - outputs: List[OutputField] = [] + outputs: List[Output] = [] """List of output fields for the frontend node.""" field_order: list[str] = [] @@ -119,9 +119,9 @@ class FrontendNode(BaseModel): # Migrate base classes to outputs if "output_types" in result: for base_class in result["output_types"]: - output = OutputField( + output = Output( name=base_class, - types=[base_class], + type=[base_class], ) result["outputs"].append(output.model_dump()) @@ -156,7 +156,7 @@ class FrontendNode(BaseModel): self.output_types.extend(output_type) @staticmethod - def format_field(field: InputField, name: Optional[str] = None) -> None: + def format_field(field: Input, name: Optional[str] = None) -> None: """Formats a given field based on its attributes and value.""" FrontendNode.get_field_formatters().format(field, name) @@ -195,7 +195,7 @@ class FrontendNode(BaseModel): return handler(field) if handler else _type @staticmethod - def handle_dict_type(field: InputField, _type: str) -> str: + def handle_dict_type(field: Input, _type: str) -> str: """Handles 'dict' type by replacing it with 'code' or 'file' based on the field name.""" if "dict" in _type.lower() and field.name == "dict_": field.field_type = "file" @@ -205,13 +205,13 @@ class FrontendNode(BaseModel): return _type @staticmethod - def replace_default_value(field: InputField, value: dict) -> None: + def replace_default_value(field: Input, value: dict) -> None: """Replaces default value with actual value if 'default' is present in value.""" if "default" in value: field.value = value["default"] @staticmethod - def handle_specific_field_values(field: InputField, key: str, name: Optional[str] = None) -> None: + def handle_specific_field_values(field: Input, key: str, name: Optional[str] = None) -> None: """Handles specific field values for certain fields.""" if key == "headers": field.value = """{"Authorization": "Bearer "}""" @@ -219,7 +219,7 @@ class FrontendNode(BaseModel): FrontendNode._handle_api_key_specific_field_values(field, key, name) @staticmethod - def _handle_model_specific_field_values(field: InputField, key: str, name: Optional[str] = None) -> None: + def _handle_model_specific_field_values(field: Input, key: str, name: Optional[str] = None) -> None: """Handles specific field values related to models.""" model_dict = { "OpenAI": constants.OPENAI_MODELS, @@ -232,7 +232,7 @@ class FrontendNode(BaseModel): field.is_list = True @staticmethod - def _handle_api_key_specific_field_values(field: InputField, key: str, name: Optional[str] = None) -> None: + def _handle_api_key_specific_field_values(field: Input, key: str, name: Optional[str] = None) -> None: """Handles specific field values related to API keys.""" if "api_key" in key and "OpenAI" in str(name): field.display_name = "OpenAI API Key" @@ -241,7 +241,7 @@ class FrontendNode(BaseModel): field.value = "" @staticmethod - def handle_kwargs_field(field: InputField) -> None: + def handle_kwargs_field(field: Input) -> None: """Handles kwargs field by setting certain attributes.""" if "kwargs" in (field.name or "").lower(): @@ -250,7 +250,7 @@ class FrontendNode(BaseModel): field.show = False @staticmethod - def handle_api_key_field(field: InputField, key: str) -> None: + def handle_api_key_field(field: Input, key: str) -> None: """Handles api key field by setting certain attributes.""" if "api" in key.lower() and "key" in key.lower(): field.required = False @@ -288,7 +288,7 @@ class FrontendNode(BaseModel): } @staticmethod - def set_field_default_value(field: InputField, value: dict, key: str) -> None: + def set_field_default_value(field: Input, value: dict, key: str) -> None: """Sets the field value with the default value if present.""" if "default" in value: field.value = value["default"] diff --git a/src/backend/base/langflow/template/frontend_node/custom_components.py b/src/backend/base/langflow/template/frontend_node/custom_components.py index d218c85a1..6969f8a73 100644 --- a/src/backend/base/langflow/template/frontend_node/custom_components.py +++ b/src/backend/base/langflow/template/frontend_node/custom_components.py @@ -1,6 +1,6 @@ from typing import Optional -from langflow.template.field.base import InputField +from langflow.template.field.base import Input from langflow.template.frontend_node.base import FrontendNode from langflow.template.template.base import Template @@ -52,7 +52,7 @@ class CustomComponentFrontendNode(FrontendNode): template: Template = Template( type_name="CustomComponent", fields=[ - InputField( + Input( field_type="code", required=True, placeholder="", diff --git a/src/backend/base/langflow/template/frontend_node/formatter/base.py b/src/backend/base/langflow/template/frontend_node/formatter/base.py index dce85d003..e2e5d8368 100644 --- a/src/backend/base/langflow/template/frontend_node/formatter/base.py +++ b/src/backend/base/langflow/template/frontend_node/formatter/base.py @@ -3,10 +3,10 @@ from typing import Optional from pydantic import BaseModel -from langflow.template.field.base import InputField +from langflow.template.field.base import Input class FieldFormatter(BaseModel, ABC): @abstractmethod - def format(self, field: InputField, name: Optional[str]) -> None: + def format(self, field: Input, name: Optional[str]) -> None: pass diff --git a/src/backend/base/langflow/template/frontend_node/formatter/field_formatters.py b/src/backend/base/langflow/template/frontend_node/formatter/field_formatters.py index 3ae5ece65..25efd079b 100644 --- a/src/backend/base/langflow/template/frontend_node/formatter/field_formatters.py +++ b/src/backend/base/langflow/template/frontend_node/formatter/field_formatters.py @@ -1,14 +1,14 @@ import re from typing import ClassVar, Dict, Optional -from langflow.template.field.base import InputField +from langflow.template.field.base import Input from langflow.template.frontend_node.constants import FORCE_SHOW_FIELDS from langflow.template.frontend_node.formatter.base import FieldFormatter from langflow.utils.constants import ANTHROPIC_MODELS, CHAT_OPENAI_MODELS, OPENAI_MODELS class OpenAIAPIKeyFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: if field.name and "api_key" in field.name and "OpenAI" in str(name): field.display_name = "OpenAI API Key" field.required = False @@ -24,14 +24,14 @@ class ModelSpecificFieldFormatter(FieldFormatter): "ChatAnthropic": ANTHROPIC_MODELS, } - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: if field.name and name in self.MODEL_DICT and field.name == "model_name": field.options = self.MODEL_DICT[name] field.is_list = True class KwargsFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: if field.name and "kwargs" in field.name.lower(): field.advanced = True field.required = False @@ -39,7 +39,7 @@ class KwargsFormatter(FieldFormatter): class APIKeyFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: if field.name and "api" in field.name.lower() and "key" in field.name.lower(): field.required = False field.advanced = False @@ -49,13 +49,13 @@ class APIKeyFormatter(FieldFormatter): class RemoveOptionalFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: _type = field.field_type field.field_type = re.sub(r"Optional\[(.*)\]", r"\1", _type) class ListTypeFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: _type = field.field_type is_list = "List" in _type or "Sequence" in _type if is_list: @@ -65,14 +65,14 @@ class ListTypeFormatter(FieldFormatter): class DictTypeFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: _type = field.field_type _type = _type.replace("Mapping", "dict") field.field_type = _type class UnionTypeFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: _type = field.field_type if "Union" in _type: _type = _type.replace("Union[", "")[:-1] @@ -87,13 +87,13 @@ class SpecialFieldFormatter(FieldFormatter): "max_value_length": lambda field: "int", } - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: handler = self.SPECIAL_FIELD_HANDLERS.get(field.name) field.field_type = handler(field) if handler else field.field_type class ShowFieldFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: key = field.name or "" required = field.required field.show = ( @@ -105,7 +105,7 @@ class ShowFieldFormatter(FieldFormatter): class PasswordFieldFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: key = field.name or "" show = field.show if any(text in key.lower() for text in {"password", "token", "api", "key"}) and show: @@ -113,7 +113,7 @@ class PasswordFieldFormatter(FieldFormatter): class MultilineFieldFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: key = field.name or "" if key in { "suffix", @@ -128,21 +128,21 @@ class MultilineFieldFormatter(FieldFormatter): class DefaultValueFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: value = field.model_dump(by_alias=True, exclude_none=True) if "default" in value: field.value = value["default"] class HeadersDefaultValueFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: key = field.name if key == "headers": field.value = """{"Authorization": "Bearer "}""" class DictCodeFileFormatter(FieldFormatter): - def format(self, field: InputField, name: Optional[str] = None) -> None: + def format(self, field: Input, name: Optional[str] = None) -> None: key = field.name value = field.model_dump(by_alias=True, exclude_none=True) _type = value["type"] diff --git a/src/backend/base/langflow/template/template/base.py b/src/backend/base/langflow/template/template/base.py index 1db5e6911..01ae4a43f 100644 --- a/src/backend/base/langflow/template/template/base.py +++ b/src/backend/base/langflow/template/template/base.py @@ -2,13 +2,13 @@ from typing import Callable, Union from pydantic import BaseModel, model_serializer -from langflow.template.field.base import InputField +from langflow.template.field.base import Input from langflow.utils.constants import DIRECT_TYPES class Template(BaseModel): type_name: str - fields: list[InputField] + fields: list[Input] def process_fields( self, @@ -38,17 +38,17 @@ class Template(BaseModel): self.sort_fields() return self.model_dump(by_alias=True, exclude_none=True, exclude={"fields"}) - def add_field(self, field: InputField) -> None: + def add_field(self, field: Input) -> None: self.fields.append(field) - def get_field(self, field_name: str) -> InputField: + def get_field(self, field_name: str) -> Input: """Returns the field with the given name.""" field = next((field for field in self.fields if field.name == field_name), None) if field is None: raise ValueError(f"Field {field_name} not found in template {self.type_name}") return field - def update_field(self, field_name: str, field: InputField) -> None: + def update_field(self, field_name: str, field: Input) -> None: """Updates the field with the given name.""" for idx, template_field in enumerate(self.fields): if template_field.name == field_name: @@ -56,7 +56,7 @@ class Template(BaseModel): return raise ValueError(f"Field {field_name} not found in template {self.type_name}") - def upsert_field(self, field_name: str, field: InputField) -> None: + def upsert_field(self, field_name: str, field: Input) -> None: """Updates the field with the given name or adds it if it doesn't exist.""" try: self.update_field(field_name, field) diff --git a/tests/data/component_with_templatefield.py b/tests/data/component_with_templatefield.py index be1ac174f..bc79c80d2 100644 --- a/tests/data/component_with_templatefield.py +++ b/tests/data/component_with_templatefield.py @@ -1,7 +1,7 @@ import random from langflow.custom import CustomComponent -from langflow.field_typing import InputField +from langflow.field_typing import Input class TestComponent(CustomComponent): @@ -11,7 +11,7 @@ class TestComponent(CustomComponent): return [f"Random {random.randint(1, 100)}" for _ in range(5)] def build_config(self): - return {"param": InputField(display_name="Param", options=self.refresh_values)} + return {"param": Input(display_name="Param", options=self.refresh_values)} def build(self, param: int): return param diff --git a/tests/test_frontend_nodes.py b/tests/test_frontend_nodes.py index 03af4332e..061526c08 100644 --- a/tests/test_frontend_nodes.py +++ b/tests/test_frontend_nodes.py @@ -1,17 +1,17 @@ import pytest -from langflow.template.field.base import InputField +from langflow.template.field.base import Input from langflow.template.frontend_node.base import FrontendNode from langflow.template.template.base import Template @pytest.fixture -def sample_template_field() -> InputField: - return InputField(name="test_field", field_type="str") +def sample_template_field() -> Input: + return Input(name="test_field", field_type="str") @pytest.fixture -def sample_template(sample_template_field: InputField) -> Template: +def sample_template(sample_template_field: Input) -> Template: return Template(type_name="test_template", fields=[sample_template_field]) @@ -25,7 +25,7 @@ def sample_frontend_node(sample_template: Template) -> FrontendNode: ) -def test_template_field_defaults(sample_template_field: InputField): +def test_template_field_defaults(sample_template_field: Input): assert sample_template_field.field_type == "str" assert sample_template_field.required is False assert sample_template_field.placeholder == "" @@ -39,7 +39,7 @@ def test_template_field_defaults(sample_template_field: InputField): assert sample_template_field.name == "test_field" -def test_template_to_dict(sample_template: Template, sample_template_field: InputField): +def test_template_to_dict(sample_template: Template, sample_template_field: Input): template_dict = sample_template.to_dict() assert template_dict["_type"] == "test_template" assert len(template_dict) == 2 # _type and test_field