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:
parent
32726cba30
commit
5c818f0b60
22 changed files with 1275 additions and 371 deletions
2
docs/static/data/AstraDB-RAG-Flows.json
vendored
2
docs/static/data/AstraDB-RAG-Flows.json
vendored
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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}.",
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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="",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue