diff --git a/src/backend/base/langflow/initial_setup/setup.py b/src/backend/base/langflow/initial_setup/setup.py index 1ae955c59..d10a6ea28 100644 --- a/src/backend/base/langflow/initial_setup/setup.py +++ b/src/backend/base/langflow/initial_setup/setup.py @@ -15,6 +15,7 @@ from loguru import logger from sqlmodel import select from langflow.base.constants import FIELD_FORMAT_ATTRIBUTES, NODE_FORMAT_ATTRIBUTES, ORJSON_OPTIONS +from langflow.graph.graph.base import Graph from langflow.interface.types import aget_all_components from langflow.services.auth.utils import create_super_user from langflow.services.database.models.flow.model import Flow, FlowCreate @@ -48,7 +49,36 @@ def update_projects_components_with_latest_component_versions(project_data, all_ if "outputs" in latest_node: node_data["outputs"] = latest_node["outputs"] if node_data["template"]["_type"] != latest_template["_type"]: - node_data["template"] = latest_template + node_data["template"]["_type"] = latest_template["_type"] + if node_data.get("display_name") != "Prompt": + node_data["template"] = latest_template + else: + for key, value in latest_template.items(): + if key not in node_data["template"]: + node_changes_log[node_data["display_name"]].append( + { + "attr": key, + "old_value": None, + "new_value": value, + } + ) + node_data["template"][key] = value + elif isinstance(value, dict) and value.get("value"): + node_changes_log[node_data["display_name"]].append( + { + "attr": key, + "old_value": node_data["template"][key], + "new_value": value, + } + ) + node_data["template"][key]["value"] = value["value"] + node_changes_log[node_data["display_name"]].append( + { + "attr": "_type", + "old_value": node_data["template"]["_type"], + "new_value": latest_template["_type"], + } + ) else: for attr in NODE_FORMAT_ATTRIBUTES: if attr in latest_node: @@ -91,6 +121,8 @@ def update_projects_components_with_latest_component_versions(project_data, all_ def scape_json_parse(json_string: str) -> dict: + if isinstance(json_string, dict): + return json_string parsed_string = json_string.replace("œ", '"') return json.loads(parsed_string) @@ -149,7 +181,7 @@ def update_new_output(data): deduplicated_outputs.append(output) source_node["data"]["node"]["outputs"] = deduplicated_outputs - edge["sourceHandle"] = json.dumps(new_source_handle) + edge["sourceHandle"] = escape_json_dump(new_source_handle) edge["data"]["sourceHandle"] = new_source_handle edge["data"]["targetHandle"] = new_target_handle # The above sets the edges but some of the sourceHandles do not have valid name @@ -164,8 +196,9 @@ def update_new_output(data): source_handle = scape_json_parse(edge["sourceHandle"]) if source_handle["output_types"] == output.get("types") and source_handle["name"] != output["name"]: source_handle["name"] = output["name"] - - edge["sourceHandle"] = json.dumps(source_handle) + if isinstance(source_handle, str): + source_handle = scape_json_parse(source_handle) + edge["sourceHandle"] = escape_json_dump(source_handle) edge["data"]["sourceHandle"] = source_handle data_copy = copy.deepcopy(data) @@ -179,7 +212,9 @@ def update_edges_with_latest_component_versions(project_data): project_data_copy = deepcopy(project_data) for edge in project_data_copy.get("edges", []): source_handle = edge.get("data").get("sourceHandle") + source_handle = scape_json_parse(source_handle) target_handle = edge.get("data").get("targetHandle") + target_handle = scape_json_parse(target_handle) # Now find the source and target nodes in the nodes list source_node = next( (node for node in project_data.get("nodes", []) if node.get("id") == edge.get("source")), None @@ -194,6 +229,17 @@ def update_edges_with_latest_component_versions(project_data): (output for output in source_node_data.get("outputs", []) if output["name"] == source_handle["name"]), None, ) + if not output_data: + output_data = next( + ( + output + for output in source_node_data.get("outputs", []) + if output["display_name"] == source_handle["name"] + ), + None, + ) + if output_data: + source_handle["name"] = output_data["name"] if output_data: if len(output_data.get("types")) == 1: new_output_types = output_data.get("types") @@ -227,20 +273,30 @@ def update_edges_with_latest_component_versions(project_data): target_handle["inputTypes"] = target_node_data.get("template").get(field_name).get("input_types") escaped_source_handle = escape_json_dump(source_handle) escaped_target_handle = escape_json_dump(target_handle) - if edge["sourceHandle"] != escaped_source_handle: + try: + old_escape_source_handle = escape_json_dump(json.loads(edge["sourceHandle"])) + + except json.JSONDecodeError: + old_escape_source_handle = edge["sourceHandle"] + + try: + old_escape_target_handle = escape_json_dump(json.loads(edge["targetHandle"])) + except json.JSONDecodeError: + old_escape_target_handle = edge["targetHandle"] + if old_escape_source_handle != escaped_source_handle: edge_changes_log[source_node_data["display_name"]].append( { "attr": "sourceHandle", - "old_value": edge["sourceHandle"], + "old_value": old_escape_source_handle, "new_value": escaped_source_handle, } ) edge["sourceHandle"] = escaped_source_handle - if edge["targetHandle"] != escaped_target_handle: + if old_escape_target_handle != escaped_target_handle: edge_changes_log[target_node_data["display_name"]].append( { "attr": "targetHandle", - "old_value": edge["targetHandle"], + "old_value": old_escape_target_handle, "new_value": escaped_target_handle, } ) @@ -498,6 +554,10 @@ async def create_or_update_starter_projects(): project_data, all_types_dict ) updated_project_data = update_edges_with_latest_component_versions(updated_project_data) + try: + Graph.from_payload(updated_project_data) + except Exception as e: + raise ValueError(f"Error loading graph from project {project_name}: {e}") if updated_project_data != project_data: project_data = updated_project_data # We also need to update the project data in the file diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json index 4544beab4..c874ee14a 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting (Hello, world!).json @@ -36,7 +36,7 @@ "sourceHandle": { "dataType": "Prompt", "id": "Prompt-uxBqP", - "name": "prompt", + "name": "Text", "output_types": [ "Prompt" ] @@ -54,7 +54,7 @@ }, "id": "reactflow__edge-Prompt-uxBqP{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-uxBqPœ}-OpenAIModel-k39HS{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-k39HSœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", "source": "Prompt-uxBqP", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-uxBqPœ, œoutput_typesœ: [œPromptœ], œnameœ: œpromptœ}", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-uxBqPœ, œoutput_typesœ: [œPromptœ], œnameœ: œTextœ}", "style": { "stroke": "#555" }, @@ -68,9 +68,7 @@ "dataType": "ChatInput", "id": "ChatInput-P3fgL", "name": "message", - "output_types": [ - "Text" - ] + "output_types": [] }, "targetHandle": { "fieldName": "user_input", @@ -86,7 +84,7 @@ }, "id": "reactflow__edge-ChatInput-P3fgL{œbaseClassesœ:[œobjectœ,œRecordœ,œstrœ,œTextœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-P3fgLœ}-Prompt-uxBqP{œfieldNameœ:œuser_inputœ,œidœ:œPrompt-uxBqPœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", "source": "ChatInput-P3fgL", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-P3fgLœ, œoutput_typesœ: [œTextœ], œnameœ: œmessageœ}", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-P3fgLœ, œoutput_typesœ: [], œnameœ: œmessageœ}", "style": { "stroke": "#555" }, @@ -125,33 +123,22 @@ "is_input": null, "is_output": null, "name": "", - "output_types": [], + "output_types": [ + "Prompt" + ], "outputs": [ { - "cache": true, - "display_name": "Prompt", - "method": "build_prompt", - "name": "prompt", - "selected": "Prompt", + "display_name": null, + "method": null, + "name": "Prompt", + "selected": null, "types": [ "Prompt" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Text", - "method": "format_prompt", - "name": "text", - "selected": "Text", - "types": [ - "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { - "_type": "Component", + "_type": "CustomComponent", "code": { "advanced": true, "dynamic": true, @@ -168,7 +155,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.custom import Component\nfrom langflow.field_typing import Input, Output\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n }\n\n inputs = [\n Input(name=\"template\", type=Prompt, display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt\", name=\"prompt\", method=\"build_prompt\"),\n Output(display_name=\"Text\", name=\"text\", method=\"format_prompt\"),\n ]\n\n async def format_prompt(self) -> str:\n prompt = await self.build_prompt()\n formatted_text = prompt.format_text()\n self.status = formatted_text\n return formatted_text\n\n async def build_prompt(\n self,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(self.template, self.kwargs)\n self.status = prompt.format_text()\n return prompt\n" + "value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import Input\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n" }, "template": { "advanced": false, @@ -189,6 +176,32 @@ "required": false, "show": true, "title_case": false, + "type": "prompt", + "value": "Answer the user as if you were a pirate.\n\nUser: {user_input}\n\nAnswer: " + }, + "user_input": { + "advanced": false, + "display_name": "user_input", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "user_input", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, "type": "str", "value": "" } @@ -256,15 +269,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Text", "selected": null, "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { @@ -533,26 +544,22 @@ "output_types": [], "outputs": [ { - "cache": true, - "display_name": "Text", + "display_name": "Message", "method": "text_response", - "name": "text", + "name": "message", "selected": "Text", "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] }, { - "cache": true, - "display_name": "Message", - "method": "message_response", - "name": "message", - "selected": "Message", + "display_name": "Record", + "method": "record_response", + "name": "record", + "selected": "Record", "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "Record" + ] } ], "template": { @@ -573,11 +580,11 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Text\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Message, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)):\n self.store_message(message)\n self.status = message\n return message\n" + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Message\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"record_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Record, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def record_response(self) -> Record:\n record = Record(\n data={\n \"message\": self.input_value,\n \"sender\": self.sender,\n \"sender_name\": self.sender_name,\n \"session_id\": self.session_id,\n \"template\": self.record_template or \"\",\n }\n )\n if self.session_id and isinstance(record, (Record, str)):\n self.store_message(record, self.session_id, self.sender, self.sender_name)\n return record\n" }, "input_value": { "advanced": false, - "display_name": "Text", + "display_name": "Message", "dynamic": false, "fileTypes": [], "file_path": "", @@ -736,26 +743,22 @@ "output_types": [], "outputs": [ { - "cache": true, "display_name": "Message", "method": "text_response", "name": "message", "selected": "Text", "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] }, { - "cache": true, "display_name": "Record", - "method": "message_response", + "method": "record_response", "name": "record", - "selected": "Message", + "selected": "Record", "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "Record" + ] } ], "template": { @@ -776,11 +779,11 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\nfrom langflow.template import Input, Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n Input(\n name=\"input_value\",\n type=str,\n display_name=\"Text\",\n multiline=True,\n input_types=[],\n info=\"Message to be passed as input.\",\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"User\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"message_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Message, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)):\n self.store_message(message)\n self.status = message\n return message\n" + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\nfrom langflow.template import Input, Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n Input(\n name=\"input_value\",\n type=str,\n display_name=\"Message\",\n multiline=True,\n input_types=[],\n info=\"Message to be passed as input.\",\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"User\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"record_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Record, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def record_response(self) -> Record:\n record = Record(\n data={\n \"text\": self.input_value,\n \"sender\": self.sender,\n \"sender_name\": self.sender_name,\n \"session_id\": self.session_id,\n },\n )\n if self.session_id and isinstance(record, (Record, str)):\n self.store_message(record, self.session_id, self.sender, self.sender_name)\n return record\n" }, "input_value": { "advanced": false, - "display_name": "Text", + "display_name": "Message", "dynamic": false, "fileTypes": [], "file_path": "", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json index fa4454aa0..7308c2a43 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Blog Writter.json @@ -133,7 +133,7 @@ "sourceHandle": { "dataType": "Prompt", "id": "Prompt-Rse03", - "name": "prompt", + "name": "Text", "output_types": [ "Prompt" ] @@ -152,7 +152,7 @@ "id": "reactflow__edge-Prompt-Rse03{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-Rse03œ}-OpenAIModel-gi29P{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-gi29Pœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", "selected": false, "source": "Prompt-Rse03", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-Rse03œ, œoutput_typesœ: [œPromptœ], œnameœ: œpromptœ}", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-Rse03œ, œoutput_typesœ: [œPromptœ], œnameœ: œTextœ}", "style": { "stroke": "#555" }, @@ -193,33 +193,22 @@ "is_input": null, "is_output": null, "name": "", - "output_types": [], + "output_types": [ + "Prompt" + ], "outputs": [ { - "cache": true, - "display_name": "Prompt", - "method": "build_prompt", - "name": "prompt", - "selected": "Prompt", + "display_name": null, + "method": null, + "name": "Prompt", + "selected": null, "types": [ "Prompt" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Text", - "method": "format_prompt", - "name": "text", - "selected": "Text", - "types": [ - "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { - "_type": "Component", + "_type": "CustomComponent", "code": { "advanced": true, "dynamic": true, @@ -236,7 +225,85 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.custom import Component\nfrom langflow.field_typing import Input, Output\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n }\n\n inputs = [\n Input(name=\"template\", type=Prompt, display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt\", name=\"prompt\", method=\"build_prompt\"),\n Output(display_name=\"Text\", name=\"text\", method=\"format_prompt\"),\n ]\n\n async def format_prompt(self) -> str:\n prompt = await self.build_prompt()\n formatted_text = prompt.format_text()\n self.status = formatted_text\n return formatted_text\n\n async def build_prompt(\n self,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(self.template, self.kwargs)\n self.status = prompt.format_text()\n return prompt\n" + "value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import Input\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n" + }, + "instructions": { + "advanced": false, + "display_name": "instructions", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "instructions", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "reference_1": { + "advanced": false, + "display_name": "reference_1", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "reference_1", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "reference_2": { + "advanced": false, + "display_name": "reference_2", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "reference_2", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" }, "template": { "advanced": false, @@ -257,8 +324,8 @@ "required": false, "show": true, "title_case": false, - "type": "str", - "value": "" + "type": "prompt", + "value": "Reference 1:\n\n{reference_1}\n\n---\n\nReference 2:\n\n{reference_2}\n\n---\n\n{instructions}\n\nBlog: \n\n\n" } } }, @@ -302,15 +369,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Record", "selected": null, "types": [ "Record" - ], - "value": "__UNDEFINED__" + ] } ], "template": { @@ -405,26 +470,22 @@ "output_types": [], "outputs": [ { - "cache": true, - "display_name": "Text", + "display_name": "Message", "method": "text_response", - "name": "text", + "name": "message", "selected": "Text", "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] }, { - "cache": true, - "display_name": "Message", - "method": "message_response", - "name": "message", - "selected": "Message", + "display_name": "Record", + "method": "record_response", + "name": "record", + "selected": "Record", "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "Record" + ] } ], "template": { @@ -445,11 +506,11 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Text\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Message, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)):\n self.store_message(message)\n self.status = message\n return message\n" + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Message\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"record_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Record, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def record_response(self) -> Record:\n record = Record(\n data={\n \"message\": self.input_value,\n \"sender\": self.sender,\n \"sender_name\": self.sender_name,\n \"session_id\": self.session_id,\n \"template\": self.record_template or \"\",\n }\n )\n if self.session_id and isinstance(record, (Record, str)):\n self.store_message(record, self.session_id, self.sender, self.sender_name)\n return record\n" }, "input_value": { "advanced": false, - "display_name": "Text", + "display_name": "Message", "dynamic": false, "fileTypes": [], "file_path": "", @@ -618,15 +679,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Text", "selected": null, "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { @@ -889,15 +948,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Record", "selected": null, "types": [ "Record" - ], - "value": "__UNDEFINED__" + ] } ], "template": { diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json index 33fbe993b..d56409f3e 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Document QA.json @@ -8,9 +8,7 @@ "dataType": "ChatInput", "id": "ChatInput-MsSJ9", "name": "message", - "output_types": [ - "Text" - ] + "output_types": [] }, "targetHandle": { "fieldName": "Question", @@ -26,7 +24,7 @@ }, "id": "reactflow__edge-ChatInput-MsSJ9{œbaseClassesœ:[œstrœ,œRecordœ,œTextœ,œobjectœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-MsSJ9œ}-Prompt-tHwPf{œfieldNameœ:œQuestionœ,œidœ:œPrompt-tHwPfœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", "source": "ChatInput-MsSJ9", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-MsSJ9œ, œoutput_typesœ: [œTextœ], œnameœ: œmessageœ}", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-MsSJ9œ, œoutput_typesœ: [], œnameœ: œmessageœ}", "style": { "stroke": "#555" }, @@ -71,7 +69,7 @@ "sourceHandle": { "dataType": "Prompt", "id": "Prompt-tHwPf", - "name": "prompt", + "name": "Text", "output_types": [ "Prompt" ] @@ -89,7 +87,7 @@ }, "id": "reactflow__edge-Prompt-tHwPf{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-tHwPfœ}-OpenAIModel-Bt067{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-Bt067œ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", "source": "Prompt-tHwPf", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-tHwPfœ, œoutput_typesœ: [œPromptœ], œnameœ: œpromptœ}", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-tHwPfœ, œoutput_typesœ: [œPromptœ], œnameœ: œTextœ}", "style": { "stroke": "#555" }, @@ -158,33 +156,74 @@ "is_input": null, "is_output": null, "name": "", - "output_types": [], + "output_types": [ + "Prompt" + ], "outputs": [ { - "cache": true, - "display_name": "Prompt", - "method": "build_prompt", - "name": "prompt", - "selected": "Prompt", + "display_name": null, + "method": null, + "name": "Prompt", + "selected": null, "types": [ "Prompt" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Text", - "method": "format_prompt", - "name": "text", - "selected": "Text", - "types": [ - "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { - "_type": "Component", + "Document": { + "advanced": false, + "display_name": "Document", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "Document", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "Question": { + "advanced": false, + "display_name": "Question", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "Question", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "_type": "CustomComponent", "code": { "advanced": true, "dynamic": true, @@ -201,7 +240,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.custom import Component\nfrom langflow.field_typing import Input, Output\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n }\n\n inputs = [\n Input(name=\"template\", type=Prompt, display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt\", name=\"prompt\", method=\"build_prompt\"),\n Output(display_name=\"Text\", name=\"text\", method=\"format_prompt\"),\n ]\n\n async def format_prompt(self) -> str:\n prompt = await self.build_prompt()\n formatted_text = prompt.format_text()\n self.status = formatted_text\n return formatted_text\n\n async def build_prompt(\n self,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(self.template, self.kwargs)\n self.status = prompt.format_text()\n return prompt\n" + "value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import Input\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n" }, "template": { "advanced": false, @@ -222,8 +261,8 @@ "required": false, "show": true, "title_case": false, - "type": "str", - "value": "" + "type": "prompt", + "value": "Answer user's questions based on the document below:\n\n---\n\n{Document}\n\n---\n\nQuestion:\n{Question}\n\nAnswer:\n" } } }, @@ -391,26 +430,22 @@ "output_types": [], "outputs": [ { - "cache": true, "display_name": "Message", "method": "text_response", "name": "message", "selected": "Text", "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] }, { - "cache": true, "display_name": "Record", - "method": "message_response", + "method": "record_response", "name": "record", - "selected": "Message", + "selected": "Record", "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "Record" + ] } ], "template": { @@ -431,11 +466,11 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\nfrom langflow.template import Input, Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n Input(\n name=\"input_value\",\n type=str,\n display_name=\"Text\",\n multiline=True,\n input_types=[],\n info=\"Message to be passed as input.\",\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"User\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"message_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Message, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)):\n self.store_message(message)\n self.status = message\n return message\n" + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\nfrom langflow.template import Input, Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n Input(\n name=\"input_value\",\n type=str,\n display_name=\"Message\",\n multiline=True,\n input_types=[],\n info=\"Message to be passed as input.\",\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"User\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"record_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Record, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def record_response(self) -> Record:\n record = Record(\n data={\n \"text\": self.input_value,\n \"sender\": self.sender,\n \"sender_name\": self.sender_name,\n \"session_id\": self.session_id,\n },\n )\n if self.session_id and isinstance(record, (Record, str)):\n self.store_message(record, self.session_id, self.sender, self.sender_name)\n return record\n" }, "input_value": { "advanced": false, - "display_name": "Text", + "display_name": "Message", "dynamic": false, "fileTypes": [], "file_path": "", @@ -570,26 +605,22 @@ "output_types": [], "outputs": [ { - "cache": true, - "display_name": "Text", + "display_name": "Message", "method": "text_response", - "name": "text", + "name": "message", "selected": "Text", "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] }, { - "cache": true, - "display_name": "Message", - "method": "message_response", - "name": "message", - "selected": "Message", + "display_name": "Record", + "method": "record_response", + "name": "record", + "selected": "Record", "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "Record" + ] } ], "template": { @@ -610,11 +641,11 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Text\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Message, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)):\n self.store_message(message)\n self.status = message\n return message\n" + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Message\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"record_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Record, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def record_response(self) -> Record:\n record = Record(\n data={\n \"message\": self.input_value,\n \"sender\": self.sender,\n \"sender_name\": self.sender_name,\n \"session_id\": self.session_id,\n \"template\": self.record_template or \"\",\n }\n )\n if self.session_id and isinstance(record, (Record, str)):\n self.store_message(record, self.session_id, self.sender, self.sender_name)\n return record\n" }, "input_value": { "advanced": false, - "display_name": "Text", + "display_name": "Message", "dynamic": false, "fileTypes": [], "file_path": "", @@ -788,15 +819,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Text", "selected": null, "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json index 0f3f2d66c..645852fe9 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json @@ -41,9 +41,7 @@ "dataType": "ChatInput", "id": "ChatInput-t7F8v", "name": "message", - "output_types": [ - "Text" - ] + "output_types": [] }, "targetHandle": { "fieldName": "user_message", @@ -60,7 +58,7 @@ "id": "reactflow__edge-ChatInput-t7F8v{œbaseClassesœ:[œTextœ,œobjectœ,œRecordœ,œstrœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-t7F8vœ}-Prompt-ODkUx{œfieldNameœ:œuser_messageœ,œidœ:œPrompt-ODkUxœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", "selected": false, "source": "ChatInput-t7F8v", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-t7F8vœ, œoutput_typesœ: [œTextœ], œnameœ: œmessageœ}", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-t7F8vœ, œoutput_typesœ: [], œnameœ: œmessageœ}", "style": { "stroke": "#555" }, @@ -73,7 +71,7 @@ "sourceHandle": { "dataType": "Prompt", "id": "Prompt-ODkUx", - "name": "prompt", + "name": "Text", "output_types": [ "Prompt" ] @@ -91,7 +89,7 @@ }, "id": "reactflow__edge-Prompt-ODkUx{œbaseClassesœ:[œTextœ,œstrœ,œobjectœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-ODkUxœ}-OpenAIModel-9RykF{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-9RykFœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", "source": "Prompt-ODkUx", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-ODkUxœ, œoutput_typesœ: [œPromptœ], œnameœ: œpromptœ}", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-ODkUxœ, œoutput_typesœ: [œPromptœ], œnameœ: œTextœ}", "style": { "stroke": "#555" }, @@ -187,26 +185,22 @@ "output_types": [], "outputs": [ { - "cache": true, "display_name": "Message", "method": "text_response", "name": "message", "selected": "Text", "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] }, { - "cache": true, "display_name": "Record", - "method": "message_response", + "method": "record_response", "name": "record", - "selected": "Message", + "selected": "Record", "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "Record" + ] } ], "template": { @@ -227,11 +221,11 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\nfrom langflow.template import Input, Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n Input(\n name=\"input_value\",\n type=str,\n display_name=\"Text\",\n multiline=True,\n input_types=[],\n info=\"Message to be passed as input.\",\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"User\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"message_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Message, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)):\n self.store_message(message)\n self.status = message\n return message\n" + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\nfrom langflow.template import Input, Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n Input(\n name=\"input_value\",\n type=str,\n display_name=\"Message\",\n multiline=True,\n input_types=[],\n info=\"Message to be passed as input.\",\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"User\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"record_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Record, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def record_response(self) -> Record:\n record = Record(\n data={\n \"text\": self.input_value,\n \"sender\": self.sender,\n \"sender_name\": self.sender_name,\n \"session_id\": self.session_id,\n },\n )\n if self.session_id and isinstance(record, (Record, str)):\n self.store_message(record, self.session_id, self.sender, self.sender_name)\n return record\n" }, "input_value": { "advanced": false, - "display_name": "Text", + "display_name": "Message", "dynamic": false, "fileTypes": [], "file_path": "", @@ -366,26 +360,22 @@ "output_types": [], "outputs": [ { - "cache": true, - "display_name": "Text", + "display_name": "Message", "method": "text_response", - "name": "text", + "name": "message", "selected": "Text", "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] }, { - "cache": true, - "display_name": "Message", - "method": "message_response", - "name": "message", - "selected": "Message", + "display_name": "Record", + "method": "record_response", + "name": "record", + "selected": "Record", "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "Record" + ] } ], "template": { @@ -406,11 +396,11 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Text\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Message, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)):\n self.store_message(message)\n self.status = message\n return message\n" + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Message\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"record_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Record, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def record_response(self) -> Record:\n record = Record(\n data={\n \"message\": self.input_value,\n \"sender\": self.sender,\n \"sender_name\": self.sender_name,\n \"session_id\": self.session_id,\n \"template\": self.record_template or \"\",\n }\n )\n if self.session_id and isinstance(record, (Record, str)):\n self.store_message(record, self.session_id, self.sender, self.sender_name)\n return record\n" }, "input_value": { "advanced": false, - "display_name": "Text", + "display_name": "Message", "dynamic": false, "fileTypes": [], "file_path": "", @@ -573,15 +563,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Text", "selected": null, "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { @@ -791,33 +779,22 @@ "is_input": null, "is_output": null, "name": "", - "output_types": [], + "output_types": [ + "Prompt" + ], "outputs": [ { - "cache": true, - "display_name": "Prompt", - "method": "build_prompt", - "name": "prompt", - "selected": "Prompt", + "display_name": null, + "method": null, + "name": "Prompt", + "selected": null, "types": [ "Prompt" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Text", - "method": "format_prompt", - "name": "text", - "selected": "Text", - "types": [ - "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { - "_type": "Component", + "_type": "CustomComponent", "code": { "advanced": true, "dynamic": true, @@ -834,7 +811,33 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.custom import Component\nfrom langflow.field_typing import Input, Output\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n }\n\n inputs = [\n Input(name=\"template\", type=Prompt, display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt\", name=\"prompt\", method=\"build_prompt\"),\n Output(display_name=\"Text\", name=\"text\", method=\"format_prompt\"),\n ]\n\n async def format_prompt(self) -> str:\n prompt = await self.build_prompt()\n formatted_text = prompt.format_text()\n self.status = formatted_text\n return formatted_text\n\n async def build_prompt(\n self,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(self.template, self.kwargs)\n self.status = prompt.format_text()\n return prompt\n" + "value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import Input\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n" + }, + "context": { + "advanced": false, + "display_name": "context", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "context", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" }, "template": { "advanced": false, @@ -855,6 +858,32 @@ "required": false, "show": true, "title_case": false, + "type": "prompt", + "value": "{context}\n\nUser: {user_message}\nAI: " + }, + "user_message": { + "advanced": false, + "display_name": "user_message", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "user_message", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, "type": "str", "value": "" } @@ -920,15 +949,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Text", "selected": null, "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json index e52a6e17b..21e3504d4 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Prompt Chaining.json @@ -8,9 +8,7 @@ "dataType": "TextInput", "id": "TextInput-sptaH", "name": "text", - "output_types": [ - "Text" - ] + "output_types": [] }, "targetHandle": { "fieldName": "document", @@ -26,7 +24,7 @@ }, "id": "reactflow__edge-TextInput-sptaH{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œTextInputœ,œidœ:œTextInput-sptaHœ}-Prompt-amqBu{œfieldNameœ:œdocumentœ,œidœ:œPrompt-amqBuœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", "source": "TextInput-sptaH", - "sourceHandle": "{œdataTypeœ: œTextInputœ, œidœ: œTextInput-sptaHœ, œoutput_typesœ: [œTextœ], œnameœ: œtextœ}", + "sourceHandle": "{œdataTypeœ: œTextInputœ, œidœ: œTextInput-sptaHœ, œoutput_typesœ: [], œnameœ: œtextœ}", "style": { "stroke": "#555" }, @@ -40,7 +38,9 @@ "dataType": "Prompt", "id": "Prompt-amqBu", "name": "Text", - "output_types": [] + "output_types": [ + "Prompt" + ] }, "targetHandle": { "fieldName": "input_value", @@ -54,7 +54,7 @@ }, "id": "reactflow__edge-Prompt-amqBu{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-amqBuœ}-TextOutput-2MS4a{œfieldNameœ:œinput_valueœ,œidœ:œTextOutput-2MS4aœ,œinputTypesœ:[œRecordœ,œTextœ],œtypeœ:œstrœ}", "source": "Prompt-amqBu", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-amqBuœ, œoutput_typesœ: [], œnameœ: œTextœ}", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-amqBuœ, œoutput_typesœ: [œPromptœ], œnameœ: œTextœ}", "style": { "stroke": "#555" }, @@ -67,7 +67,7 @@ "sourceHandle": { "dataType": "Prompt", "id": "Prompt-amqBu", - "name": "prompt", + "name": "Text", "output_types": [ "Prompt" ] @@ -85,7 +85,7 @@ }, "id": "reactflow__edge-Prompt-amqBu{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-amqBuœ}-OpenAIModel-uYXZJ{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-uYXZJœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", "source": "Prompt-amqBu", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-amqBuœ, œoutput_typesœ: [œPromptœ], œnameœ: œpromptœ}", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-amqBuœ, œoutput_typesœ: [œPromptœ], œnameœ: œTextœ}", "style": { "stroke": "#555" }, @@ -160,7 +160,9 @@ "dataType": "Prompt", "id": "Prompt-gTNiz", "name": "Text", - "output_types": [] + "output_types": [ + "Prompt" + ] }, "targetHandle": { "fieldName": "input_value", @@ -174,7 +176,7 @@ }, "id": "reactflow__edge-Prompt-gTNiz{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-gTNizœ}-TextOutput-MUDOR{œfieldNameœ:œinput_valueœ,œidœ:œTextOutput-MUDORœ,œinputTypesœ:[œRecordœ,œTextœ],œtypeœ:œstrœ}", "source": "Prompt-gTNiz", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-gTNizœ, œoutput_typesœ: [], œnameœ: œTextœ}", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-gTNizœ, œoutput_typesœ: [œPromptœ], œnameœ: œTextœ}", "style": { "stroke": "#555" }, @@ -187,7 +189,7 @@ "sourceHandle": { "dataType": "Prompt", "id": "Prompt-gTNiz", - "name": "prompt", + "name": "Text", "output_types": [ "Prompt" ] @@ -205,7 +207,7 @@ }, "id": "reactflow__edge-Prompt-gTNiz{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-gTNizœ}-OpenAIModel-XawYB{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-XawYBœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", "source": "Prompt-gTNiz", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-gTNizœ, œoutput_typesœ: [œPromptœ], œnameœ: œpromptœ}", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-gTNizœ, œoutput_typesœ: [œPromptœ], œnameœ: œTextœ}", "style": { "stroke": "#555" }, @@ -273,33 +275,22 @@ "is_input": null, "is_output": null, "name": "", - "output_types": [], + "output_types": [ + "Prompt" + ], "outputs": [ { - "cache": true, - "display_name": "Prompt", - "method": "build_prompt", - "name": "prompt", - "selected": "Prompt", + "display_name": null, + "method": null, + "name": "Prompt", + "selected": null, "types": [ "Prompt" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Text", - "method": "format_prompt", - "name": "text", - "selected": "Text", - "types": [ - "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { - "_type": "Component", + "_type": "CustomComponent", "code": { "advanced": true, "dynamic": true, @@ -316,7 +307,33 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.custom import Component\nfrom langflow.field_typing import Input, Output\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n }\n\n inputs = [\n Input(name=\"template\", type=Prompt, display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt\", name=\"prompt\", method=\"build_prompt\"),\n Output(display_name=\"Text\", name=\"text\", method=\"format_prompt\"),\n ]\n\n async def format_prompt(self) -> str:\n prompt = await self.build_prompt()\n formatted_text = prompt.format_text()\n self.status = formatted_text\n return formatted_text\n\n async def build_prompt(\n self,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(self.template, self.kwargs)\n self.status = prompt.format_text()\n return prompt\n" + "value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import Input\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n" + }, + "document": { + "advanced": false, + "display_name": "document", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "document", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" }, "template": { "advanced": false, @@ -337,8 +354,8 @@ "required": false, "show": true, "title_case": false, - "type": "str", - "value": "" + "type": "prompt", + "value": "You are a helpful assistant. Given a long document, your task is to create a concise summary that captures the main points and key details. The summary should be clear, accurate, and succinct. Please provide the summary in the format below:\n####\n{document}\n####\n" } } }, @@ -389,33 +406,22 @@ "is_input": null, "is_output": null, "name": "", - "output_types": [], + "output_types": [ + "Prompt" + ], "outputs": [ { - "cache": true, - "display_name": "Prompt", - "method": "build_prompt", - "name": "prompt", - "selected": "Prompt", + "display_name": null, + "method": null, + "name": "Prompt", + "selected": null, "types": [ "Prompt" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Text", - "method": "format_prompt", - "name": "text", - "selected": "Text", - "types": [ - "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { - "_type": "Component", + "_type": "CustomComponent", "code": { "advanced": true, "dynamic": true, @@ -432,7 +438,33 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.custom import Component\nfrom langflow.field_typing import Input, Output\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n }\n\n inputs = [\n Input(name=\"template\", type=Prompt, display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt\", name=\"prompt\", method=\"build_prompt\"),\n Output(display_name=\"Text\", name=\"text\", method=\"format_prompt\"),\n ]\n\n async def format_prompt(self) -> str:\n prompt = await self.build_prompt()\n formatted_text = prompt.format_text()\n self.status = formatted_text\n return formatted_text\n\n async def build_prompt(\n self,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(self.template, self.kwargs)\n self.status = prompt.format_text()\n return prompt\n" + "value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import Input\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n" + }, + "summary": { + "advanced": false, + "display_name": "summary", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "summary", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" }, "template": { "advanced": false, @@ -453,8 +485,8 @@ "required": false, "show": true, "title_case": false, - "type": "str", - "value": "" + "type": "prompt", + "value": "Given a summary of an article, please create two multiple-choice questions that cover the key points and details mentioned. Ensure the questions are clear and provide three options (A, B, C), with one correct answer.\n####\n{summary}\n####" } } }, @@ -500,26 +532,22 @@ "output_types": [], "outputs": [ { - "cache": true, - "display_name": "Text", + "display_name": "Message", "method": "text_response", - "name": "text", + "name": "message", "selected": "Text", "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] }, { - "cache": true, - "display_name": "Message", - "method": "message_response", - "name": "message", - "selected": "Message", + "display_name": "Record", + "method": "record_response", + "name": "record", + "selected": "Record", "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "Record" + ] } ], "template": { @@ -540,11 +568,11 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Text\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Message, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)):\n self.store_message(message)\n self.status = message\n return message\n" + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Message\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"record_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Record, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def record_response(self) -> Record:\n record = Record(\n data={\n \"message\": self.input_value,\n \"sender\": self.sender,\n \"sender_name\": self.sender_name,\n \"session_id\": self.session_id,\n \"template\": self.record_template or \"\",\n }\n )\n if self.session_id and isinstance(record, (Record, str)):\n self.store_message(record, self.session_id, self.sender, self.sender_name)\n return record\n" }, "input_value": { "advanced": false, - "display_name": "Text", + "display_name": "Message", "dynamic": false, "fileTypes": [], "file_path": "", @@ -700,26 +728,22 @@ "output_types": [], "outputs": [ { - "cache": true, - "display_name": "Text", + "display_name": "Message", "method": "text_response", - "name": "text", + "name": "message", "selected": "Text", "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] }, { - "cache": true, - "display_name": "Message", - "method": "message_response", - "name": "message", - "selected": "Message", + "display_name": "Record", + "method": "record_response", + "name": "record", + "selected": "Record", "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "Record" + ] } ], "template": { @@ -740,11 +764,11 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Text\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Message, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)):\n self.store_message(message)\n self.status = message\n return message\n" + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Message\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"record_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Record, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def record_response(self) -> Record:\n record = Record(\n data={\n \"message\": self.input_value,\n \"sender\": self.sender,\n \"sender_name\": self.sender_name,\n \"session_id\": self.session_id,\n \"template\": self.record_template or \"\",\n }\n )\n if self.session_id and isinstance(record, (Record, str)):\n self.store_message(record, self.session_id, self.sender, self.sender_name)\n return record\n" }, "input_value": { "advanced": false, - "display_name": "Text", + "display_name": "Message", "dynamic": false, "fileTypes": [], "file_path": "", @@ -894,15 +918,13 @@ "output_types": [], "outputs": [ { - "cache": true, "display_name": "Text", "method": "text_response", "name": "text", "selected": "Text", "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { @@ -1140,15 +1162,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Text", "selected": null, "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { @@ -1539,15 +1559,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Text", "selected": null, "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { diff --git a/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json b/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json index 8a1d0a3ac..67af1468b 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json @@ -41,9 +41,7 @@ "dataType": "ChatInput", "id": "ChatInput-yxMKE", "name": "message", - "output_types": [ - "Text" - ] + "output_types": [] }, "targetHandle": { "fieldName": "question", @@ -60,7 +58,7 @@ "id": "reactflow__edge-ChatInput-yxMKE{œbaseClassesœ:[œTextœ,œstrœ,œobjectœ,œRecordœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-yxMKEœ}-Prompt-xeI6K{œfieldNameœ:œquestionœ,œidœ:œPrompt-xeI6Kœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", "selected": false, "source": "ChatInput-yxMKE", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-yxMKEœ, œoutput_typesœ: [œTextœ], œnameœ: œmessageœ}", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-yxMKEœ, œoutput_typesœ: [], œnameœ: œmessageœ}", "style": { "stroke": "#555" }, @@ -73,7 +71,7 @@ "sourceHandle": { "dataType": "Prompt", "id": "Prompt-xeI6K", - "name": "prompt", + "name": "Text", "output_types": [ "Prompt" ] @@ -92,7 +90,7 @@ "id": "reactflow__edge-Prompt-xeI6K{œbaseClassesœ:[œobjectœ,œTextœ,œstrœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-xeI6Kœ}-OpenAIModel-EjXlN{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-EjXlNœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", "selected": false, "source": "Prompt-xeI6K", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-xeI6Kœ, œoutput_typesœ: [œPromptœ], œnameœ: œpromptœ}", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-xeI6Kœ, œoutput_typesœ: [œPromptœ], œnameœ: œTextœ}", "style": { "stroke": "#555" }, @@ -194,9 +192,7 @@ "dataType": "ChatInput", "id": "ChatInput-yxMKE", "name": "message", - "output_types": [ - "Text" - ] + "output_types": [] }, "targetHandle": { "fieldName": "input_value", @@ -209,7 +205,7 @@ }, "id": "reactflow__edge-ChatInput-yxMKE{œbaseClassesœ:[œTextœ,œstrœ,œobjectœ,œRecordœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-yxMKEœ}-AstraDBSearch-41nRz{œfieldNameœ:œinput_valueœ,œidœ:œAstraDBSearch-41nRzœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", "source": "ChatInput-yxMKE", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-yxMKEœ, œoutput_typesœ: [œTextœ], œnameœ: œmessageœ}", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-yxMKEœ, œoutput_typesœ: [], œnameœ: œmessageœ}", "style": { "stroke": "#555" }, @@ -332,26 +328,22 @@ "output_types": [], "outputs": [ { - "cache": true, "display_name": "Message", "method": "text_response", "name": "message", "selected": "Text", "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] }, { - "cache": true, "display_name": "Record", - "method": "message_response", + "method": "record_response", "name": "record", - "selected": "Message", + "selected": "Record", "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "Record" + ] } ], "template": { @@ -372,11 +364,11 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\nfrom langflow.template import Input, Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n Input(\n name=\"input_value\",\n type=str,\n display_name=\"Text\",\n multiline=True,\n input_types=[],\n info=\"Message to be passed as input.\",\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"User\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"message_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Message, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)):\n self.store_message(message)\n self.status = message\n return message\n" + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\nfrom langflow.template import Input, Output\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n inputs = [\n Input(\n name=\"input_value\",\n type=str,\n display_name=\"Message\",\n multiline=True,\n input_types=[],\n info=\"Message to be passed as input.\",\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"User\",\n info=\"Type of sender.\",\n advanced=True,\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"User\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"record_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Record, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def record_response(self) -> Record:\n record = Record(\n data={\n \"text\": self.input_value,\n \"sender\": self.sender,\n \"sender_name\": self.sender_name,\n \"session_id\": self.session_id,\n },\n )\n if self.session_id and isinstance(record, (Record, str)):\n self.store_message(record, self.session_id, self.sender, self.sender_name)\n return record\n" }, "input_value": { "advanced": false, - "display_name": "Text", + "display_name": "Message", "dynamic": false, "fileTypes": [], "file_path": "", @@ -638,15 +630,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Embeddings", "selected": null, "types": [ "Embeddings" - ], - "value": "__UNDEFINED__" + ] } ], "template": { @@ -1164,15 +1154,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Text", "selected": null, "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { @@ -1443,33 +1431,22 @@ "is_input": null, "is_output": null, "name": "", - "output_types": [], + "output_types": [ + "Prompt" + ], "outputs": [ { - "cache": true, - "display_name": "Prompt", - "method": "build_prompt", - "name": "prompt", - "selected": "Prompt", + "display_name": null, + "method": null, + "name": "Prompt", + "selected": null, "types": [ "Prompt" - ], - "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Text", - "method": "format_prompt", - "name": "text", - "selected": "Text", - "types": [ - "Text" - ], - "value": "__UNDEFINED__" + ] } ], "template": { - "_type": "Component", + "_type": "CustomComponent", "code": { "advanced": true, "dynamic": true, @@ -1486,7 +1463,59 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.custom import Component\nfrom langflow.field_typing import Input, Output\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n }\n\n inputs = [\n Input(name=\"template\", type=Prompt, display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt\", name=\"prompt\", method=\"build_prompt\"),\n Output(display_name=\"Text\", name=\"text\", method=\"format_prompt\"),\n ]\n\n async def format_prompt(self) -> str:\n prompt = await self.build_prompt()\n formatted_text = prompt.format_text()\n self.status = formatted_text\n return formatted_text\n\n async def build_prompt(\n self,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(self.template, self.kwargs)\n self.status = prompt.format_text()\n return prompt\n" + "value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import Input\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": Input(display_name=\"Template\"),\n \"code\": Input(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n" + }, + "context": { + "advanced": false, + "display_name": "context", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "context", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "question": { + "advanced": false, + "display_name": "question", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "question", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" }, "template": { "advanced": false, @@ -1507,8 +1536,8 @@ "required": false, "show": true, "title_case": false, - "type": "str", - "value": "" + "type": "prompt", + "value": "{context}\n\n---\n\nGiven the context above, answer the question as best as possible.\n\nQuestion: {question}\n\nAnswer: " } } }, @@ -1558,26 +1587,22 @@ "output_types": [], "outputs": [ { - "cache": true, - "display_name": "Text", + "display_name": "Message", "method": "text_response", - "name": "text", + "name": "message", "selected": "Text", "types": [ "Text" - ], - "value": "__UNDEFINED__" + ] }, { - "cache": true, - "display_name": "Message", - "method": "message_response", - "name": "message", - "selected": "Message", + "display_name": "Record", + "method": "record_response", + "name": "record", + "selected": "Record", "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "Record" + ] } ], "template": { @@ -1598,11 +1623,11 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Text\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Text\", name=\"text\", method=\"text_response\"),\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Message, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if self.session_id and isinstance(message, (Message, str)):\n self.store_message(message)\n self.status = message\n return message\n" + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\nfrom langflow.template import Input, Output\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n inputs = [\n Input(\n name=\"input_value\", type=str, display_name=\"Message\", multiline=True, info=\"Message to be passed as output.\"\n ),\n Input(\n name=\"sender\",\n type=str,\n display_name=\"Sender Type\",\n options=[\"Machine\", \"User\"],\n value=\"Machine\",\n advanced=True,\n info=\"Type of sender.\",\n ),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\", info=\"Name of the sender.\", value=\"AI\"),\n Input(\n name=\"session_id\", type=str, display_name=\"Session ID\", info=\"Session ID for the message.\", advanced=True\n ),\n Input(\n name=\"record_template\",\n type=str,\n display_name=\"Record Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"text_response\"),\n Output(display_name=\"Record\", name=\"record\", method=\"record_response\"),\n ]\n\n def text_response(self) -> Text:\n result = self.input_value\n if self.session_id and isinstance(result, (Record, str)):\n self.store_message(result, self.session_id, self.sender, self.sender_name)\n return result\n\n def record_response(self) -> Record:\n record = Record(\n data={\n \"message\": self.input_value,\n \"sender\": self.sender,\n \"sender_name\": self.sender_name,\n \"session_id\": self.session_id,\n \"template\": self.record_template or \"\",\n }\n )\n if self.session_id and isinstance(record, (Record, str)):\n self.store_message(record, self.session_id, self.sender, self.sender_name)\n return record\n" }, "input_value": { "advanced": false, - "display_name": "Text", + "display_name": "Message", "dynamic": false, "fileTypes": [], "file_path": "", @@ -1757,15 +1782,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Record", "selected": null, "types": [ "Record" - ], - "value": "__UNDEFINED__" + ] } ], "template": { @@ -1889,15 +1912,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Record", "selected": null, "types": [ "Record" - ], - "value": "__UNDEFINED__" + ] } ], "template": { @@ -2069,15 +2090,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Record", "selected": null, "types": [ "Record" - ], - "value": "__UNDEFINED__" + ] } ], "template": { @@ -2534,26 +2553,22 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "VectorStore", "selected": null, "types": [ "VectorStore" - ], - "value": "__UNDEFINED__" + ] }, { - "cache": true, "display_name": null, "method": null, "name": "BaseRetriever", "selected": null, "types": [ "BaseRetriever" - ], - "value": "__UNDEFINED__" + ] } ], "template": { @@ -2668,7 +2683,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from typing import List, Optional, Union\n\nfrom langchain_core.retrievers import BaseRetriever\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, VectorStore\nfrom langflow.schema import Record\n\n\nclass AstraDBVectorStoreComponent(CustomComponent):\n display_name = \"Astra DB\"\n description = \"Builds or loads an Astra DB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"inputs\", \"embedding\"]\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Inputs\",\n \"info\": \"Optional list of records to be processed and stored in the vector store.\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within Astra DB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing Astra DB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the Astra DB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within Astra DB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n token: str,\n api_endpoint: str,\n collection_name: str,\n inputs: Optional[List[Record]] = None,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Sync\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> Union[VectorStore, BaseRetriever]:\n try:\n from langchain_astradb import AstraDBVectorStore\n from langchain_astradb.utils.astradb import SetupMode\n except ImportError:\n raise ImportError(\n \"Could not import langchain Astra DB integration package. \"\n \"Please install it with `pip install langchain-astradb`.\"\n )\n\n try:\n setup_mode_value = SetupMode[setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {setup_mode}\")\n if inputs:\n documents = [_input.to_lc_document() for _input in inputs]\n\n vector_store = AstraDBVectorStore.from_documents(\n documents=documents,\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n else:\n vector_store = AstraDBVectorStore(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n\n return vector_store\n return vector_store\n" + "value": "from typing import List, Optional, Union\n\nfrom langchain_astradb import AstraDBVectorStore\nfrom langchain_astradb.utils.astradb import SetupMode\nfrom langchain_core.retrievers import BaseRetriever\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, VectorStore\nfrom langflow.schema import Record\n\n\nclass AstraDBVectorStoreComponent(CustomComponent):\n display_name = \"Astra DB\"\n description = \"Builds or loads an Astra DB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"inputs\", \"embedding\"]\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Inputs\",\n \"info\": \"Optional list of records to be processed and stored in the vector store.\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within Astra DB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing Astra DB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the Astra DB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within Astra DB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n token: str,\n api_endpoint: str,\n collection_name: str,\n inputs: Optional[List[Record]] = None,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Sync\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> Union[VectorStore, BaseRetriever]:\n try:\n setup_mode_value = SetupMode[setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {setup_mode}\")\n if inputs:\n documents = [_input.to_lc_document() for _input in inputs]\n\n vector_store = AstraDBVectorStore.from_documents(\n documents=documents,\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n else:\n vector_store = AstraDBVectorStore(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n\n return vector_store\n return vector_store\n" }, "collection_indexing_policy": { "advanced": true, @@ -2960,15 +2975,13 @@ ], "outputs": [ { - "cache": true, "display_name": null, "method": null, "name": "Embeddings", "selected": null, "types": [ "Embeddings" - ], - "value": "__UNDEFINED__" + ] } ], "template": { diff --git a/src/backend/base/langflow/template/frontend_node/base.py b/src/backend/base/langflow/template/frontend_node/base.py index be4efc92a..6d9a1d397 100644 --- a/src/backend/base/langflow/template/frontend_node/base.py +++ b/src/backend/base/langflow/template/frontend_node/base.py @@ -76,11 +76,10 @@ class FrontendNode(BaseModel): name = result.pop("name") # Migrate base classes to outputs - if "output_types" in result: + if "output_types" in result and not result.get("outputs"): for base_class in result["output_types"]: output = Output( - name=base_class, - types=[base_class], + display_name=base_class, name=base_class.lower(), types=[base_class], selected=base_class ) result["outputs"].append(output.model_dump())