diff --git a/src/backend/base/langflow/components/helpers/structured_output.py b/src/backend/base/langflow/components/helpers/structured_output.py index 701573009..36301d1fe 100644 --- a/src/backend/base/langflow/components/helpers/structured_output.py +++ b/src/backend/base/langflow/components/helpers/structured_output.py @@ -5,7 +5,14 @@ from pydantic import BaseModel, Field, create_model from langflow.base.models.chat_result import get_chat_result from langflow.custom import Component from langflow.helpers.base_model import build_model_from_schema -from langflow.io import BoolInput, HandleInput, MessageTextInput, MultilineInput, Output, TableInput +from langflow.io import ( + BoolInput, + HandleInput, + MessageTextInput, + MultilineInput, + Output, + TableInput, +) from langflow.schema.data import Data from langflow.schema.dataframe import DataFrame from langflow.schema.table import EditMode @@ -92,7 +99,8 @@ class StructuredOutputComponent(Component): "description": ( "Indicate the data type of the output field (e.g., str, int, float, bool, list, dict)." ), - "default": "text", + "options": ["str", "int", "float", "bool", "list", "dict"], + "default": "str", }, { "name": "multiple", @@ -103,7 +111,14 @@ class StructuredOutputComponent(Component): "edit_mode": EditMode.INLINE, }, ], - value=[{"name": "field", "description": "description of field", "type": "text", "multiple": "False"}], + value=[ + { + "name": "field", + "description": "description of field", + "type": "str", + "multiple": "False", + } + ], ), BoolInput( name="multiple", @@ -115,8 +130,16 @@ class StructuredOutputComponent(Component): ] outputs = [ - Output(name="structured_output", display_name="Structured Output", method="build_structured_output"), - Output(name="structured_output_dataframe", display_name="DataFrame", method="as_dataframe"), + Output( + name="structured_output", + display_name="Structured Output", + method="build_structured_output", + ), + Output( + name="structured_output_dataframe", + display_name="DataFrame", + method="as_dataframe", + ), ] def build_structured_output_base(self) -> Data: diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json b/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json index 07481c7f6..8a127a5a2 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json @@ -1251,7 +1251,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from typing import TYPE_CHECKING, cast\n\nfrom pydantic import BaseModel, Field, create_model\n\nfrom langflow.base.models.chat_result import get_chat_result\nfrom langflow.custom import Component\nfrom langflow.helpers.base_model import build_model_from_schema\nfrom langflow.io import BoolInput, HandleInput, MessageTextInput, MultilineInput, Output, TableInput\nfrom langflow.schema.data import Data\nfrom langflow.schema.dataframe import DataFrame\nfrom langflow.schema.table import EditMode\n\nif TYPE_CHECKING:\n from langflow.field_typing.constants import LanguageModel\n\n\nclass StructuredOutputComponent(Component):\n display_name = \"Structured Output\"\n description = (\n \"Transforms LLM responses into **structured data formats**. Ideal for extracting specific information \"\n \"or creating consistent outputs.\"\n )\n name = \"StructuredOutput\"\n icon = \"braces\"\n\n inputs = [\n HandleInput(\n name=\"llm\",\n display_name=\"Language Model\",\n info=\"The language model to use to generate the structured output.\",\n input_types=[\"LanguageModel\"],\n required=True,\n ),\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Input Message\",\n info=\"The input message to the language model.\",\n tool_mode=True,\n required=True,\n ),\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"Format Instructions\",\n info=\"The instructions to the language model for formatting the output.\",\n value=(\n \"You are an AI system designed to extract structured information from unstructured text.\"\n \"Given the input_text, return a JSON object with predefined keys based on the expected structure.\"\n \"Extract values accurately and format them according to the specified type \"\n \"(e.g., string, integer, float, date).\"\n \"If a value is missing or cannot be determined, return a default \"\n \"(e.g., null, 0, or 'N/A').\"\n \"If multiple instances of the expected structure exist within the input_text, \"\n \"stream each as a separate JSON object.\"\n ),\n required=True,\n advanced=True,\n ),\n MessageTextInput(\n name=\"schema_name\",\n display_name=\"Schema Name\",\n info=\"Provide a name for the output data schema.\",\n advanced=True,\n ),\n TableInput(\n name=\"output_schema\",\n display_name=\"Output Schema\",\n info=\"Define the structure and data types for the model's output.\",\n required=True,\n # TODO: remove deault value\n table_schema=[\n {\n \"name\": \"name\",\n \"display_name\": \"Name\",\n \"type\": \"str\",\n \"description\": \"Specify the name of the output field.\",\n \"default\": \"field\",\n \"edit_mode\": EditMode.INLINE,\n },\n {\n \"name\": \"description\",\n \"display_name\": \"Description\",\n \"type\": \"str\",\n \"description\": \"Describe the purpose of the output field.\",\n \"default\": \"description of field\",\n \"edit_mode\": EditMode.POPOVER,\n },\n {\n \"name\": \"type\",\n \"display_name\": \"Type\",\n \"type\": \"str\",\n \"edit_mode\": EditMode.INLINE,\n \"description\": (\n \"Indicate the data type of the output field (e.g., str, int, float, bool, list, dict).\"\n ),\n \"default\": \"text\",\n },\n {\n \"name\": \"multiple\",\n \"display_name\": \"Multiple\",\n \"type\": \"boolean\",\n \"description\": \"Set to True if this output field should be a list of the specified type.\",\n \"default\": \"False\",\n \"edit_mode\": EditMode.INLINE,\n },\n ],\n value=[{\"name\": \"field\", \"description\": \"description of field\", \"type\": \"text\", \"multiple\": \"False\"}],\n ),\n BoolInput(\n name=\"multiple\",\n advanced=True,\n display_name=\"Generate Multiple\",\n info=\"[Deplrecated] Always set to True\",\n value=True,\n ),\n ]\n\n outputs = [\n Output(name=\"structured_output\", display_name=\"Structured Output\", method=\"build_structured_output\"),\n Output(name=\"structured_output_dataframe\", display_name=\"DataFrame\", method=\"as_dataframe\"),\n ]\n\n def build_structured_output_base(self) -> Data:\n schema_name = self.schema_name or \"OutputModel\"\n\n if not hasattr(self.llm, \"with_structured_output\"):\n msg = \"Language model does not support structured output.\"\n raise TypeError(msg)\n if not self.output_schema:\n msg = \"Output schema cannot be empty\"\n raise ValueError(msg)\n\n output_model_ = build_model_from_schema(self.output_schema)\n\n output_model = create_model(\n schema_name,\n objects=(list[output_model_], Field(description=f\"A list of {schema_name}.\")), # type: ignore[valid-type]\n )\n\n try:\n llm_with_structured_output = cast(\"LanguageModel\", self.llm).with_structured_output(schema=output_model) # type: ignore[valid-type, attr-defined]\n\n except NotImplementedError as exc:\n msg = f\"{self.llm.__class__.__name__} does not support structured output.\"\n raise TypeError(msg) from exc\n config_dict = {\n \"run_name\": self.display_name,\n \"project_name\": self.get_project_name(),\n \"callbacks\": self.get_langchain_callbacks(),\n }\n result = get_chat_result(\n runnable=llm_with_structured_output,\n system_message=self.system_prompt,\n input_value=self.input_value,\n config=config_dict,\n )\n if isinstance(result, BaseModel):\n result = result.model_dump()\n if \"objects\" in result:\n return result[\"objects\"]\n return result\n\n def build_structured_output(self) -> Data:\n output = self.build_structured_output_base()\n\n return Data(results=output)\n\n def as_dataframe(self) -> DataFrame:\n output = self.build_structured_output_base()\n if isinstance(output, list):\n return DataFrame(data=output)\n return DataFrame(data=[output])\n" + "value": "from typing import TYPE_CHECKING, cast\n\nfrom pydantic import BaseModel, Field, create_model\n\nfrom langflow.base.models.chat_result import get_chat_result\nfrom langflow.custom import Component\nfrom langflow.helpers.base_model import build_model_from_schema\nfrom langflow.io import (\n BoolInput,\n HandleInput,\n MessageTextInput,\n MultilineInput,\n Output,\n TableInput,\n)\nfrom langflow.schema.data import Data\nfrom langflow.schema.dataframe import DataFrame\nfrom langflow.schema.table import EditMode\n\nif TYPE_CHECKING:\n from langflow.field_typing.constants import LanguageModel\n\n\nclass StructuredOutputComponent(Component):\n display_name = \"Structured Output\"\n description = (\n \"Transforms LLM responses into **structured data formats**. Ideal for extracting specific information \"\n \"or creating consistent outputs.\"\n )\n name = \"StructuredOutput\"\n icon = \"braces\"\n\n inputs = [\n HandleInput(\n name=\"llm\",\n display_name=\"Language Model\",\n info=\"The language model to use to generate the structured output.\",\n input_types=[\"LanguageModel\"],\n required=True,\n ),\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Input Message\",\n info=\"The input message to the language model.\",\n tool_mode=True,\n required=True,\n ),\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"Format Instructions\",\n info=\"The instructions to the language model for formatting the output.\",\n value=(\n \"You are an AI system designed to extract structured information from unstructured text.\"\n \"Given the input_text, return a JSON object with predefined keys based on the expected structure.\"\n \"Extract values accurately and format them according to the specified type \"\n \"(e.g., string, integer, float, date).\"\n \"If a value is missing or cannot be determined, return a default \"\n \"(e.g., null, 0, or 'N/A').\"\n \"If multiple instances of the expected structure exist within the input_text, \"\n \"stream each as a separate JSON object.\"\n ),\n required=True,\n advanced=True,\n ),\n MessageTextInput(\n name=\"schema_name\",\n display_name=\"Schema Name\",\n info=\"Provide a name for the output data schema.\",\n advanced=True,\n ),\n TableInput(\n name=\"output_schema\",\n display_name=\"Output Schema\",\n info=\"Define the structure and data types for the model's output.\",\n required=True,\n # TODO: remove deault value\n table_schema=[\n {\n \"name\": \"name\",\n \"display_name\": \"Name\",\n \"type\": \"str\",\n \"description\": \"Specify the name of the output field.\",\n \"default\": \"field\",\n \"edit_mode\": EditMode.INLINE,\n },\n {\n \"name\": \"description\",\n \"display_name\": \"Description\",\n \"type\": \"str\",\n \"description\": \"Describe the purpose of the output field.\",\n \"default\": \"description of field\",\n \"edit_mode\": EditMode.POPOVER,\n },\n {\n \"name\": \"type\",\n \"display_name\": \"Type\",\n \"type\": \"str\",\n \"edit_mode\": EditMode.INLINE,\n \"description\": (\n \"Indicate the data type of the output field (e.g., str, int, float, bool, list, dict).\"\n ),\n \"options\": [\"str\", \"int\", \"float\", \"bool\", \"list\", \"dict\"],\n \"default\": \"str\",\n },\n {\n \"name\": \"multiple\",\n \"display_name\": \"Multiple\",\n \"type\": \"boolean\",\n \"description\": \"Set to True if this output field should be a list of the specified type.\",\n \"default\": \"False\",\n \"edit_mode\": EditMode.INLINE,\n },\n ],\n value=[\n {\n \"name\": \"field\",\n \"description\": \"description of field\",\n \"type\": \"str\",\n \"multiple\": \"False\",\n }\n ],\n ),\n BoolInput(\n name=\"multiple\",\n advanced=True,\n display_name=\"Generate Multiple\",\n info=\"[Deplrecated] Always set to True\",\n value=True,\n ),\n ]\n\n outputs = [\n Output(\n name=\"structured_output\",\n display_name=\"Structured Output\",\n method=\"build_structured_output\",\n ),\n Output(\n name=\"structured_output_dataframe\",\n display_name=\"DataFrame\",\n method=\"as_dataframe\",\n ),\n ]\n\n def build_structured_output_base(self) -> Data:\n schema_name = self.schema_name or \"OutputModel\"\n\n if not hasattr(self.llm, \"with_structured_output\"):\n msg = \"Language model does not support structured output.\"\n raise TypeError(msg)\n if not self.output_schema:\n msg = \"Output schema cannot be empty\"\n raise ValueError(msg)\n\n output_model_ = build_model_from_schema(self.output_schema)\n\n output_model = create_model(\n schema_name,\n objects=(list[output_model_], Field(description=f\"A list of {schema_name}.\")), # type: ignore[valid-type]\n )\n\n try:\n llm_with_structured_output = cast(\"LanguageModel\", self.llm).with_structured_output(schema=output_model) # type: ignore[valid-type, attr-defined]\n\n except NotImplementedError as exc:\n msg = f\"{self.llm.__class__.__name__} does not support structured output.\"\n raise TypeError(msg) from exc\n config_dict = {\n \"run_name\": self.display_name,\n \"project_name\": self.get_project_name(),\n \"callbacks\": self.get_langchain_callbacks(),\n }\n result = get_chat_result(\n runnable=llm_with_structured_output,\n system_message=self.system_prompt,\n input_value=self.input_value,\n config=config_dict,\n )\n if isinstance(result, BaseModel):\n result = result.model_dump()\n if \"objects\" in result:\n return result[\"objects\"]\n return result\n\n def build_structured_output(self) -> Data:\n output = self.build_structured_output_base()\n\n return Data(results=output)\n\n def as_dataframe(self) -> DataFrame:\n output = self.build_structured_output_base()\n if isinstance(output, list):\n return DataFrame(data=output)\n return DataFrame(data=[output])\n" }, "input_value": { "_input_type": "MessageTextInput", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json b/src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json index 670a5e4ee..f8c8226d8 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json @@ -1823,7 +1823,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from typing import TYPE_CHECKING, cast\n\nfrom pydantic import BaseModel, Field, create_model\n\nfrom langflow.base.models.chat_result import get_chat_result\nfrom langflow.custom import Component\nfrom langflow.helpers.base_model import build_model_from_schema\nfrom langflow.io import BoolInput, HandleInput, MessageTextInput, MultilineInput, Output, TableInput\nfrom langflow.schema.data import Data\nfrom langflow.schema.dataframe import DataFrame\nfrom langflow.schema.table import EditMode\n\nif TYPE_CHECKING:\n from langflow.field_typing.constants import LanguageModel\n\n\nclass StructuredOutputComponent(Component):\n display_name = \"Structured Output\"\n description = (\n \"Transforms LLM responses into **structured data formats**. Ideal for extracting specific information \"\n \"or creating consistent outputs.\"\n )\n name = \"StructuredOutput\"\n icon = \"braces\"\n\n inputs = [\n HandleInput(\n name=\"llm\",\n display_name=\"Language Model\",\n info=\"The language model to use to generate the structured output.\",\n input_types=[\"LanguageModel\"],\n required=True,\n ),\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Input Message\",\n info=\"The input message to the language model.\",\n tool_mode=True,\n required=True,\n ),\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"Format Instructions\",\n info=\"The instructions to the language model for formatting the output.\",\n value=(\n \"You are an AI system designed to extract structured information from unstructured text.\"\n \"Given the input_text, return a JSON object with predefined keys based on the expected structure.\"\n \"Extract values accurately and format them according to the specified type \"\n \"(e.g., string, integer, float, date).\"\n \"If a value is missing or cannot be determined, return a default \"\n \"(e.g., null, 0, or 'N/A').\"\n \"If multiple instances of the expected structure exist within the input_text, \"\n \"stream each as a separate JSON object.\"\n ),\n required=True,\n advanced=True,\n ),\n MessageTextInput(\n name=\"schema_name\",\n display_name=\"Schema Name\",\n info=\"Provide a name for the output data schema.\",\n advanced=True,\n ),\n TableInput(\n name=\"output_schema\",\n display_name=\"Output Schema\",\n info=\"Define the structure and data types for the model's output.\",\n required=True,\n # TODO: remove deault value\n table_schema=[\n {\n \"name\": \"name\",\n \"display_name\": \"Name\",\n \"type\": \"str\",\n \"description\": \"Specify the name of the output field.\",\n \"default\": \"field\",\n \"edit_mode\": EditMode.INLINE,\n },\n {\n \"name\": \"description\",\n \"display_name\": \"Description\",\n \"type\": \"str\",\n \"description\": \"Describe the purpose of the output field.\",\n \"default\": \"description of field\",\n \"edit_mode\": EditMode.POPOVER,\n },\n {\n \"name\": \"type\",\n \"display_name\": \"Type\",\n \"type\": \"str\",\n \"edit_mode\": EditMode.INLINE,\n \"description\": (\n \"Indicate the data type of the output field (e.g., str, int, float, bool, list, dict).\"\n ),\n \"default\": \"text\",\n },\n {\n \"name\": \"multiple\",\n \"display_name\": \"Multiple\",\n \"type\": \"boolean\",\n \"description\": \"Set to True if this output field should be a list of the specified type.\",\n \"default\": \"False\",\n \"edit_mode\": EditMode.INLINE,\n },\n ],\n value=[{\"name\": \"field\", \"description\": \"description of field\", \"type\": \"text\", \"multiple\": \"False\"}],\n ),\n BoolInput(\n name=\"multiple\",\n advanced=True,\n display_name=\"Generate Multiple\",\n info=\"[Deplrecated] Always set to True\",\n value=True,\n ),\n ]\n\n outputs = [\n Output(name=\"structured_output\", display_name=\"Structured Output\", method=\"build_structured_output\"),\n Output(name=\"structured_output_dataframe\", display_name=\"DataFrame\", method=\"as_dataframe\"),\n ]\n\n def build_structured_output_base(self) -> Data:\n schema_name = self.schema_name or \"OutputModel\"\n\n if not hasattr(self.llm, \"with_structured_output\"):\n msg = \"Language model does not support structured output.\"\n raise TypeError(msg)\n if not self.output_schema:\n msg = \"Output schema cannot be empty\"\n raise ValueError(msg)\n\n output_model_ = build_model_from_schema(self.output_schema)\n\n output_model = create_model(\n schema_name,\n objects=(list[output_model_], Field(description=f\"A list of {schema_name}.\")), # type: ignore[valid-type]\n )\n\n try:\n llm_with_structured_output = cast(\"LanguageModel\", self.llm).with_structured_output(schema=output_model) # type: ignore[valid-type, attr-defined]\n\n except NotImplementedError as exc:\n msg = f\"{self.llm.__class__.__name__} does not support structured output.\"\n raise TypeError(msg) from exc\n config_dict = {\n \"run_name\": self.display_name,\n \"project_name\": self.get_project_name(),\n \"callbacks\": self.get_langchain_callbacks(),\n }\n result = get_chat_result(\n runnable=llm_with_structured_output,\n system_message=self.system_prompt,\n input_value=self.input_value,\n config=config_dict,\n )\n if isinstance(result, BaseModel):\n result = result.model_dump()\n if \"objects\" in result:\n return result[\"objects\"]\n return result\n\n def build_structured_output(self) -> Data:\n output = self.build_structured_output_base()\n\n return Data(results=output)\n\n def as_dataframe(self) -> DataFrame:\n output = self.build_structured_output_base()\n if isinstance(output, list):\n return DataFrame(data=output)\n return DataFrame(data=[output])\n" + "value": "from typing import TYPE_CHECKING, cast\n\nfrom pydantic import BaseModel, Field, create_model\n\nfrom langflow.base.models.chat_result import get_chat_result\nfrom langflow.custom import Component\nfrom langflow.helpers.base_model import build_model_from_schema\nfrom langflow.io import (\n BoolInput,\n HandleInput,\n MessageTextInput,\n MultilineInput,\n Output,\n TableInput,\n)\nfrom langflow.schema.data import Data\nfrom langflow.schema.dataframe import DataFrame\nfrom langflow.schema.table import EditMode\n\nif TYPE_CHECKING:\n from langflow.field_typing.constants import LanguageModel\n\n\nclass StructuredOutputComponent(Component):\n display_name = \"Structured Output\"\n description = (\n \"Transforms LLM responses into **structured data formats**. Ideal for extracting specific information \"\n \"or creating consistent outputs.\"\n )\n name = \"StructuredOutput\"\n icon = \"braces\"\n\n inputs = [\n HandleInput(\n name=\"llm\",\n display_name=\"Language Model\",\n info=\"The language model to use to generate the structured output.\",\n input_types=[\"LanguageModel\"],\n required=True,\n ),\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Input Message\",\n info=\"The input message to the language model.\",\n tool_mode=True,\n required=True,\n ),\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"Format Instructions\",\n info=\"The instructions to the language model for formatting the output.\",\n value=(\n \"You are an AI system designed to extract structured information from unstructured text.\"\n \"Given the input_text, return a JSON object with predefined keys based on the expected structure.\"\n \"Extract values accurately and format them according to the specified type \"\n \"(e.g., string, integer, float, date).\"\n \"If a value is missing or cannot be determined, return a default \"\n \"(e.g., null, 0, or 'N/A').\"\n \"If multiple instances of the expected structure exist within the input_text, \"\n \"stream each as a separate JSON object.\"\n ),\n required=True,\n advanced=True,\n ),\n MessageTextInput(\n name=\"schema_name\",\n display_name=\"Schema Name\",\n info=\"Provide a name for the output data schema.\",\n advanced=True,\n ),\n TableInput(\n name=\"output_schema\",\n display_name=\"Output Schema\",\n info=\"Define the structure and data types for the model's output.\",\n required=True,\n # TODO: remove deault value\n table_schema=[\n {\n \"name\": \"name\",\n \"display_name\": \"Name\",\n \"type\": \"str\",\n \"description\": \"Specify the name of the output field.\",\n \"default\": \"field\",\n \"edit_mode\": EditMode.INLINE,\n },\n {\n \"name\": \"description\",\n \"display_name\": \"Description\",\n \"type\": \"str\",\n \"description\": \"Describe the purpose of the output field.\",\n \"default\": \"description of field\",\n \"edit_mode\": EditMode.POPOVER,\n },\n {\n \"name\": \"type\",\n \"display_name\": \"Type\",\n \"type\": \"str\",\n \"edit_mode\": EditMode.INLINE,\n \"description\": (\n \"Indicate the data type of the output field (e.g., str, int, float, bool, list, dict).\"\n ),\n \"options\": [\"str\", \"int\", \"float\", \"bool\", \"list\", \"dict\"],\n \"default\": \"str\",\n },\n {\n \"name\": \"multiple\",\n \"display_name\": \"Multiple\",\n \"type\": \"boolean\",\n \"description\": \"Set to True if this output field should be a list of the specified type.\",\n \"default\": \"False\",\n \"edit_mode\": EditMode.INLINE,\n },\n ],\n value=[\n {\n \"name\": \"field\",\n \"description\": \"description of field\",\n \"type\": \"str\",\n \"multiple\": \"False\",\n }\n ],\n ),\n BoolInput(\n name=\"multiple\",\n advanced=True,\n display_name=\"Generate Multiple\",\n info=\"[Deplrecated] Always set to True\",\n value=True,\n ),\n ]\n\n outputs = [\n Output(\n name=\"structured_output\",\n display_name=\"Structured Output\",\n method=\"build_structured_output\",\n ),\n Output(\n name=\"structured_output_dataframe\",\n display_name=\"DataFrame\",\n method=\"as_dataframe\",\n ),\n ]\n\n def build_structured_output_base(self) -> Data:\n schema_name = self.schema_name or \"OutputModel\"\n\n if not hasattr(self.llm, \"with_structured_output\"):\n msg = \"Language model does not support structured output.\"\n raise TypeError(msg)\n if not self.output_schema:\n msg = \"Output schema cannot be empty\"\n raise ValueError(msg)\n\n output_model_ = build_model_from_schema(self.output_schema)\n\n output_model = create_model(\n schema_name,\n objects=(list[output_model_], Field(description=f\"A list of {schema_name}.\")), # type: ignore[valid-type]\n )\n\n try:\n llm_with_structured_output = cast(\"LanguageModel\", self.llm).with_structured_output(schema=output_model) # type: ignore[valid-type, attr-defined]\n\n except NotImplementedError as exc:\n msg = f\"{self.llm.__class__.__name__} does not support structured output.\"\n raise TypeError(msg) from exc\n config_dict = {\n \"run_name\": self.display_name,\n \"project_name\": self.get_project_name(),\n \"callbacks\": self.get_langchain_callbacks(),\n }\n result = get_chat_result(\n runnable=llm_with_structured_output,\n system_message=self.system_prompt,\n input_value=self.input_value,\n config=config_dict,\n )\n if isinstance(result, BaseModel):\n result = result.model_dump()\n if \"objects\" in result:\n return result[\"objects\"]\n return result\n\n def build_structured_output(self) -> Data:\n output = self.build_structured_output_base()\n\n return Data(results=output)\n\n def as_dataframe(self) -> DataFrame:\n output = self.build_structured_output_base()\n if isinstance(output, list):\n return DataFrame(data=output)\n return DataFrame(data=[output])\n" }, "input_value": { "_input_type": "MessageTextInput", diff --git a/src/backend/base/langflow/schema/table.py b/src/backend/base/langflow/schema/table.py index 541204551..7cb5dfe54 100644 --- a/src/backend/base/langflow/schema/table.py +++ b/src/backend/base/langflow/schema/table.py @@ -34,6 +34,7 @@ class Column(BaseModel): model_config = ConfigDict(populate_by_name=True) name: str display_name: str = Field(default="") + options: list[str] | None = Field(default=None) sortable: bool = Field(default=True) filterable: bool = Field(default=True) formatter: FormatterType | str | None = Field(default=None) diff --git a/src/frontend/src/App.css b/src/frontend/src/App.css index f6be7e508..bb5d372eb 100644 --- a/src/frontend/src/App.css +++ b/src/frontend/src/App.css @@ -124,11 +124,12 @@ body { /* This CSS is to not apply the border for the column having 'no-border' class */ .no-border.ag-cell:focus { border: none !important; - outline: none; + outline: none !important; + box-shadow: none !important; } .no-border.ag-cell { border: none !important; - outline: none; + outline: none !important; } .react-flow__edge.selected .react-flow__edge-path { diff --git a/src/frontend/src/components/core/parameterRenderComponent/components/tableComponent/components/tableDropdownCellEditor/index.tsx b/src/frontend/src/components/core/parameterRenderComponent/components/tableComponent/components/tableDropdownCellEditor/index.tsx new file mode 100644 index 000000000..918617d86 --- /dev/null +++ b/src/frontend/src/components/core/parameterRenderComponent/components/tableComponent/components/tableDropdownCellEditor/index.tsx @@ -0,0 +1,22 @@ +import { CustomCellEditorProps } from "ag-grid-react"; +import InputComponent from "../../../inputComponent"; + +export default function TableDropdownCellEditor({ + value, + values, + onValueChange, + colDef, +}: CustomCellEditorProps & { values: string[] }) { + return ( +
+ onValueChange(value)} + value={value} + options={values} + password={false} + placeholder={"Select an option"} + id="apply-to-fields" + /> +
+ ); +} diff --git a/src/frontend/src/types/utils/functions.ts b/src/frontend/src/types/utils/functions.ts index 17816ea74..947117a04 100644 --- a/src/frontend/src/types/utils/functions.ts +++ b/src/frontend/src/types/utils/functions.ts @@ -28,4 +28,5 @@ export interface ColumnField { default?: any; edit_mode?: "modal" | "inline" | "popover"; hidden?: boolean; + options?: string[]; } diff --git a/src/frontend/src/utils/utils.ts b/src/frontend/src/utils/utils.ts index a479bbe06..1d66fe2a7 100644 --- a/src/frontend/src/utils/utils.ts +++ b/src/frontend/src/utils/utils.ts @@ -1,4 +1,5 @@ import TableAutoCellRender from "@/components/core/parameterRenderComponent/components/tableComponent/components/tableAutoCellRender"; +import TableDropdownCellEditor from "@/components/core/parameterRenderComponent/components/tableComponent/components/tableDropdownCellEditor"; import TableToggleCellEditor from "@/components/core/parameterRenderComponent/components/tableComponent/components/tableToggleCellEditor"; import useAlertStore from "@/stores/alertStore"; import { ColumnField, FormatterType } from "@/types/utils/functions"; @@ -566,8 +567,21 @@ export function FormatColumns(columns: ColumnField[]): ColDef[] { newCol.cellRendererParams = { formatter: col.formatter, }; - if (col.formatter !== FormatterType.text || col.edit_mode !== "inline") { - if ( + + if ( + col.formatter !== FormatterType.text || + col.edit_mode !== "inline" || + col.options + ) { + if (col.options && col.formatter === FormatterType.text) { + newCol.cellEditor = TableDropdownCellEditor; + newCol.cellEditorPopup = false; + newCol.cellEditorParams = { + values: col.options, + }; + newCol.autoHeight = false; + newCol.cellClass = "no-border !py-2"; + } else if ( col.edit_mode === "popover" && col.formatter === FormatterType.text ) {