feat: Update field types in prompt and formatter modules

This commit updates the field types in the `prompt.py` and `formatter/base.py` modules. The `DefaultPromptField` class in `prompt.py` now inherits from `InputField` instead of `TemplateField`. Similarly, the `format` method in the `FieldFormatter` class in `formatter/base.py` now accepts an `InputField` parameter instead of a `TemplateField` parameter. These changes ensure consistency and improve the accuracy of the code.
This commit is contained in:
ogabrielluiz 2024-05-30 16:46:45 -03:00
commit 5c818f0b60
22 changed files with 1275 additions and 371 deletions

View file

@ -1108,7 +1108,7 @@
"list": false,
"show": true,
"multiline": true,
"value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.field_typing import Prompt, TemplateField, Text\nfrom langflow.interface.custom.custom_component import CustomComponent\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\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(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.field_typing import Prompt, InputField, Text\nfrom langflow.interface.custom.custom_component import CustomComponent\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",
"fileTypes": [],
"file_path": "",
"password": false,

View file

@ -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 TemplateField
from langflow.template.field.base import InputField
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[TemplateField] = []
new_fields: list[InputField] = []
for vertex in inputs:
field = TemplateField(
field = InputField(
display_name=vertex.display_name,
name=vertex.id,
info=vertex.description,

View file

@ -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 TemplateField
from langflow.template.field.base import InputField
class CreateRecordComponent(CustomComponent):
@ -35,7 +35,7 @@ class CreateRecordComponent(CustomComponent):
field = existing_fields[key]
build_config[key] = field
else:
field = TemplateField(
field = InputField(
display_name=f"Field {i}",
name=key,
info=f"Key for field {i}.",

View file

@ -1,7 +1,7 @@
from langchain_core.prompts import PromptTemplate
from langflow.custom import CustomComponent
from langflow.field_typing import Prompt, TemplateField, Text
from langflow.field_typing import InputField, Prompt, Text
class PromptComponent(CustomComponent):
@ -11,8 +11,8 @@ class PromptComponent(CustomComponent):
def build_config(self):
return {
"template": TemplateField(display_name="Template"),
"code": TemplateField(advanced=True),
"template": InputField(display_name="Template"),
"code": InputField(advanced=True),
}
def build(

View file

@ -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 TemplateField
from langflow.template.field.base import InputField
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 = TemplateField(
new_field = InputField(
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[TemplateField, dict]):
"""Get the field dictionary from a TemplateField or a dict"""
if isinstance(field, TemplateField):
def get_field_dict(field: Union[InputField, dict]):
"""Get the field dictionary from a InputField or a dict"""
if isinstance(field, InputField):
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 TemplateField as well
# as a dict with the same keys as TemplateField
# Allow user to build InputField as well
# as a dict with the same keys as InputField
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 = TemplateField(
code_field = InputField(
dynamic=True,
required=True,
placeholder="",
@ -429,9 +429,9 @@ def update_field_dict(
return build_config
def sanitize_field_config(field_config: Union[Dict, TemplateField]):
def sanitize_field_config(field_config: Union[Dict, InputField]):
# If any of the already existing keys are in field_config, remove them
if isinstance(field_config, TemplateField):
if isinstance(field_config, InputField):
field_dict = field_config.to_dict()
else:
field_dict = field_config

View file

@ -30,14 +30,14 @@ from .range_spec import RangeSpec
def _import_template_field():
from langflow.template.field.base import TemplateField
from langflow.template.field.base import InputField
return TemplateField
return InputField
def __getattr__(name: str) -> Any:
# This is to avoid circular imports
if name == "TemplateField":
if name == "InputField":
return _import_template_field()
elif name == "RangeSpec":
return RangeSpec
@ -73,6 +73,6 @@ __all__ = [
"ChatPromptTemplate",
"Prompt",
"RangeSpec",
"TemplateField",
"InputField",
"Code",
]

View file

@ -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 Prompt, TemplateField, 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\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(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 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",
"fileTypes": [],
"file_path": "",
"password": false,

View file

@ -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 Prompt, TemplateField, 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\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(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 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",
"fileTypes": [],
"file_path": "",
"password": false,

View file

@ -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 Prompt, TemplateField, 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\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(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 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",
"fileTypes": [],
"file_path": "",
"password": false,

View file

@ -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 Prompt, TemplateField, 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\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(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 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",
"fileTypes": [],
"file_path": "",
"password": false,

View file

@ -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 Prompt, TemplateField, 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\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(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 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",
"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 Prompt, TemplateField, 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\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(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 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",
"fileTypes": [],
"file_path": "",
"password": false,

View file

@ -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 Prompt, TemplateField, 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\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(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 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",
"fileTypes": [],
"file_path": "",
"password": false,

View file

@ -5,7 +5,7 @@ from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_valid
from langflow.field_typing.range_spec import RangeSpec
class TemplateField(BaseModel):
class InputField(BaseModel):
model_config = ConfigDict()
field_type: str = Field(default="str", serialization_alias="type")
@ -128,3 +128,17 @@ class TemplateField(BaseModel):
(f".{file_type}" if isinstance(file_type, str) and not file_type.startswith(".") else file_type)
for file_type in value
]
class OutputField(BaseModel):
types: list[str] = Field(default=[], serialization_alias="types")
"""List of output types for the field."""
selected: Optional[str] = Field(default=None, serialization_alias="selected")
"""The selected output type for the field."""
name: str = Field(default="", serialization_alias="name")
"""The name of the field."""
def to_dict(self):
return self.model_dump(by_alias=True, exclude_none=True)

View file

@ -1,9 +1,9 @@
from typing import Optional
from langflow.template.field.base import TemplateField
from langflow.template.field.base import InputField
class DefaultPromptField(TemplateField):
class DefaultPromptField(InputField):
name: str
display_name: Optional[str] = None
field_type: str = "str"

View file

@ -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 TemplateField
from langflow.template.field.base import InputField
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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, name: Optional[str] = None) -> None:
for key, formatter in self.base_formatters.items():
formatter.format(field, name)
@ -145,7 +145,7 @@ class FrontendNode(BaseModel):
self.output_types.extend(output_type)
@staticmethod
def format_field(field: TemplateField, name: Optional[str] = None) -> None:
def format_field(field: InputField, name: Optional[str] = None) -> None:
"""Formats a given field based on its attributes and value."""
FrontendNode.get_field_formatters().format(field, name)
@ -184,7 +184,7 @@ class FrontendNode(BaseModel):
return handler(field) if handler else _type
@staticmethod
def handle_dict_type(field: TemplateField, _type: str) -> str:
def handle_dict_type(field: InputField, _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"
@ -194,13 +194,13 @@ class FrontendNode(BaseModel):
return _type
@staticmethod
def replace_default_value(field: TemplateField, value: dict) -> None:
def replace_default_value(field: InputField, 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: TemplateField, key: str, name: Optional[str] = None) -> None:
def handle_specific_field_values(field: InputField, key: str, name: Optional[str] = None) -> None:
"""Handles specific field values for certain fields."""
if key == "headers":
field.value = """{"Authorization": "Bearer <token>"}"""
@ -208,7 +208,7 @@ class FrontendNode(BaseModel):
FrontendNode._handle_api_key_specific_field_values(field, key, name)
@staticmethod
def _handle_model_specific_field_values(field: TemplateField, key: str, name: Optional[str] = None) -> None:
def _handle_model_specific_field_values(field: InputField, key: str, name: Optional[str] = None) -> None:
"""Handles specific field values related to models."""
model_dict = {
"OpenAI": constants.OPENAI_MODELS,
@ -221,7 +221,7 @@ class FrontendNode(BaseModel):
field.is_list = True
@staticmethod
def _handle_api_key_specific_field_values(field: TemplateField, key: str, name: Optional[str] = None) -> None:
def _handle_api_key_specific_field_values(field: InputField, 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"
@ -230,7 +230,7 @@ class FrontendNode(BaseModel):
field.value = ""
@staticmethod
def handle_kwargs_field(field: TemplateField) -> None:
def handle_kwargs_field(field: InputField) -> None:
"""Handles kwargs field by setting certain attributes."""
if "kwargs" in (field.name or "").lower():
@ -239,7 +239,7 @@ class FrontendNode(BaseModel):
field.show = False
@staticmethod
def handle_api_key_field(field: TemplateField, key: str) -> None:
def handle_api_key_field(field: InputField, key: str) -> None:
"""Handles api key field by setting certain attributes."""
if "api" in key.lower() and "key" in key.lower():
field.required = False
@ -277,7 +277,7 @@ class FrontendNode(BaseModel):
}
@staticmethod
def set_field_default_value(field: TemplateField, value: dict, key: str) -> None:
def set_field_default_value(field: InputField, value: dict, key: str) -> None:
"""Sets the field value with the default value if present."""
if "default" in value:
field.value = value["default"]

View file

@ -1,6 +1,6 @@
from typing import Optional
from langflow.template.field.base import TemplateField
from langflow.template.field.base import InputField
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=[
TemplateField(
InputField(
field_type="code",
required=True,
placeholder="",

View file

@ -3,10 +3,10 @@ from typing import Optional
from pydantic import BaseModel
from langflow.template.field.base import TemplateField
from langflow.template.field.base import InputField
class FieldFormatter(BaseModel, ABC):
@abstractmethod
def format(self, field: TemplateField, name: Optional[str]) -> None:
def format(self, field: InputField, name: Optional[str]) -> None:
pass

View file

@ -1,14 +1,14 @@
import re
from typing import ClassVar, Dict, Optional
from langflow.template.field.base import TemplateField
from langflow.template.field.base import InputField
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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, 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: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, name: Optional[str] = None) -> None:
key = field.name
if key == "headers":
field.value = """{"Authorization": "Bearer <token>"}"""
class DictCodeFileFormatter(FieldFormatter):
def format(self, field: TemplateField, name: Optional[str] = None) -> None:
def format(self, field: InputField, name: Optional[str] = None) -> None:
key = field.name
value = field.model_dump(by_alias=True, exclude_none=True)
_type = value["type"]

View file

@ -2,13 +2,13 @@ from typing import Callable, Union
from pydantic import BaseModel, model_serializer
from langflow.template.field.base import TemplateField
from langflow.template.field.base import InputField
from langflow.utils.constants import DIRECT_TYPES
class Template(BaseModel):
type_name: str
fields: list[TemplateField]
fields: list[InputField]
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: TemplateField) -> None:
def add_field(self, field: InputField) -> None:
self.fields.append(field)
def get_field(self, field_name: str) -> TemplateField:
def get_field(self, field_name: str) -> InputField:
"""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: TemplateField) -> None:
def update_field(self, field_name: str, field: InputField) -> 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: TemplateField) -> None:
def upsert_field(self, field_name: str, field: InputField) -> None:
"""Updates the field with the given name or adds it if it doesn't exist."""
try:
self.update_field(field_name, field)

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,7 @@
import random
from langflow.custom import CustomComponent
from langflow.field_typing import TemplateField
from langflow.field_typing import InputField
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": TemplateField(display_name="Param", options=self.refresh_values)}
return {"param": InputField(display_name="Param", options=self.refresh_values)}
def build(self, param: int):
return param

View file

@ -1,16 +1,17 @@
import pytest
from langflow.template.field.base import TemplateField
from langflow.template.field.base import InputField
from langflow.template.frontend_node.base import FrontendNode
from langflow.template.template.base import Template
@pytest.fixture
def sample_template_field() -> TemplateField:
return TemplateField(name="test_field", field_type="str")
def sample_template_field() -> InputField:
return InputField(name="test_field", field_type="str")
@pytest.fixture
def sample_template(sample_template_field: TemplateField) -> Template:
def sample_template(sample_template_field: InputField) -> Template:
return Template(type_name="test_template", fields=[sample_template_field])
@ -24,7 +25,7 @@ def sample_frontend_node(sample_template: Template) -> FrontendNode:
)
def test_template_field_defaults(sample_template_field: TemplateField):
def test_template_field_defaults(sample_template_field: InputField):
assert sample_template_field.field_type == "str"
assert sample_template_field.required is False
assert sample_template_field.placeholder == ""
@ -38,7 +39,7 @@ def test_template_field_defaults(sample_template_field: TemplateField):
assert sample_template_field.name == "test_field"
def test_template_to_dict(sample_template: Template, sample_template_field: TemplateField):
def test_template_to_dict(sample_template: Template, sample_template_field: InputField):
template_dict = sample_template.to_dict()
assert template_dict["_type"] == "test_template"
assert len(template_dict) == 2 # _type and test_field