diff --git a/src/backend/base/langflow/base/constants.py b/src/backend/base/langflow/base/constants.py index 498b46f65..02a58f964 100644 --- a/src/backend/base/langflow/base/constants.py +++ b/src/backend/base/langflow/base/constants.py @@ -26,4 +26,5 @@ FIELD_FORMAT_ATTRIBUTES = [ "refresh_button", "refresh_button_text", "options", + "advanced", ] diff --git a/src/backend/base/langflow/components/inputs/ChatInput.py b/src/backend/base/langflow/components/inputs/ChatInput.py index b20d73764..ae08a7a20 100644 --- a/src/backend/base/langflow/components/inputs/ChatInput.py +++ b/src/backend/base/langflow/components/inputs/ChatInput.py @@ -10,10 +10,27 @@ class ChatInput(ChatComponent): icon = "ChatInput" inputs = [ - Input(name="input_value", type=str, display_name="Message", multiline=True, input_types=[]), - Input(name="sender", type=str, display_name="Sender Type", options=["Machine", "User"]), - Input(name="sender_name", type=str, display_name="Sender Name"), - Input(name="session_id", type=str, display_name="Session ID"), + Input( + name="input_value", + type=str, + display_name="Message", + multiline=True, + input_types=[], + info="Message to be passed as input.", + ), + Input( + name="sender", + type=str, + display_name="Sender Type", + options=["Machine", "User"], + value="User", + info="Type of sender.", + advanced=True, + ), + Input(name="sender_name", type=str, display_name="Sender Name", info="Name of the sender.", value="User"), + Input( + name="session_id", type=str, display_name="Session ID", info="Session ID for the message.", advanced=True + ), ] outputs = [ Output(name="Message", method="text_response"), diff --git a/src/backend/base/langflow/components/outputs/ChatOutput.py b/src/backend/base/langflow/components/outputs/ChatOutput.py index 3e44d38aa..064cd92f1 100644 --- a/src/backend/base/langflow/components/outputs/ChatOutput.py +++ b/src/backend/base/langflow/components/outputs/ChatOutput.py @@ -10,11 +10,30 @@ class ChatOutput(ChatComponent): icon = "ChatOutput" inputs = [ - Input(name="input_value", type=str, display_name="Message", multiline=True), - Input(name="sender", type=str, display_name="Sender Type", options=["Machine", "AI"]), - Input(name="sender_name", type=str, display_name="Sender Name"), - Input(name="session_id", type=str, display_name="Session ID"), - Input(name="record_template", type=str, display_name="Record Template", default="{text}"), + Input( + name="input_value", type=str, display_name="Message", multiline=True, info="Message to be passed as output." + ), + Input( + name="sender", + type=str, + display_name="Sender Type", + options=["Machine", "User"], + value="Machine", + advanced=True, + info="Type of sender.", + ), + Input(name="sender_name", type=str, display_name="Sender Name", info="Name of the sender.", value="AI"), + Input( + name="session_id", type=str, display_name="Session ID", info="Session ID for the message.", advanced=True + ), + Input( + name="record_template", + type=str, + display_name="Record Template", + value="{text}", + advanced=True, + info="Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", + ), ] outputs = [ Output(name="Message", method="text_response"), diff --git a/src/backend/base/langflow/custom/custom_component/component.py b/src/backend/base/langflow/custom/custom_component/component.py index b5f3bfcad..551c47a08 100644 --- a/src/backend/base/langflow/custom/custom_component/component.py +++ b/src/backend/base/langflow/custom/custom_component/component.py @@ -1,9 +1,38 @@ -from typing import ClassVar, List, Optional +import inspect +from typing import TYPE_CHECKING, AsyncIterator, Awaitable, Callable, ClassVar, Generator, Iterator, List, Optional +import yaml +from loguru import logger +from pydantic import BaseModel + +from langflow.schema.schema import Record from langflow.template.field.base import Input, Output from .custom_component import CustomComponent +if TYPE_CHECKING: + from langflow.graph.vertex.base import Vertex + + +def recursive_serialize_or_str(obj): + try: + if isinstance(obj, dict): + return {k: recursive_serialize_or_str(v) for k, v in obj.items()} + elif isinstance(obj, list): + return [recursive_serialize_or_str(v) for v in obj] + elif isinstance(obj, BaseModel): + return {k: recursive_serialize_or_str(v) for k, v in obj.model_dump().items()} + elif isinstance(obj, (AsyncIterator, Generator, Iterator)): + # Turn it into something readable that does not + # contain memory addresses + # without consuming the iterator + # return list(obj) consumes the iterator + # return f"{obj}" this generates '' + # it is not useful + return "Unconsumed Stream" + except Exception: + return str(obj) + class Component(CustomComponent): inputs: Optional[List[Input]] = None @@ -15,3 +44,37 @@ class Component(CustomComponent): if key in self.__dict__: raise ValueError(f"Key {key} already exists in {self.__class__.__name__}") setattr(self, key, value) + + async def build_results(self, vertex: "Vertex"): + build_results = {} + + if hasattr(self, "outputs"): + for output in self.outputs: + # Build the output if it's connected to some other vertex + # or if it's not connected to any vertex + if not vertex.outgoing_edges or output.name in vertex.edges_source_names: + method: Callable | Awaitable = getattr(self, output.method) + result = method() + # If the method is asynchronous, we need to await it + if inspect.iscoroutinefunction(method): + result = await result + build_results[output.name] = result + self.build_results = build_results + return build_results + + def custom_repr(self): + # ! Temporary REPR + # Since all are dict, yaml.dump them + if isinstance(self.build_results, dict): + _build_results = recursive_serialize_or_str(self.build_results) + try: + custom_repr = yaml.dump(_build_results) + except Exception as e: + logger.error(f"Error while dumping build_result: {e}") + custom_repr = str(self.build_results) + + if custom_repr is None and isinstance(self.build_results, (dict, Record, str)): + custom_repr = self.build_results + if not isinstance(custom_repr, str): + custom_repr = str(custom_repr) + return custom_repr diff --git a/src/backend/base/langflow/graph/vertex/base.py b/src/backend/base/langflow/graph/vertex/base.py index bde56383f..2ced35a1c 100644 --- a/src/backend/base/langflow/graph/vertex/base.py +++ b/src/backend/base/langflow/graph/vertex/base.py @@ -217,7 +217,7 @@ class Vertex: raise ValueError(f"Outputs not found for {self.display_name}") self.outputs = self.data["node"]["outputs"] else: - self.outputs = self.data["node"]["outputs"] + self.outputs = self.data["node"].get("outputs", []) self.output = self.data["node"]["base_classes"] self.display_name = self.data["node"].get("display_name", self.id.split("-")[0]) diff --git a/src/backend/base/langflow/graph/vertex/types.py b/src/backend/base/langflow/graph/vertex/types.py index 5320d5e77..af2369fcd 100644 --- a/src/backend/base/langflow/graph/vertex/types.py +++ b/src/backend/base/langflow/graph/vertex/types.py @@ -3,7 +3,7 @@ from typing import Any, AsyncIterator, Dict, Iterator, List import yaml from git import TYPE_CHECKING -from langchain_core.messages import AIMessage +from langchain_core.messages import AIMessage, AIMessageChunk from loguru import logger from langflow.graph.schema import CHAT_COMPONENTS, RECORDS_COMPONENTS, InterfaceComponentTypes @@ -156,28 +156,32 @@ class InterfaceVertex(ComponentVertex): if isinstance(message, str): message = unescape_string(message) stream_url = None - if isinstance(self._built_object, AIMessage): + text_output = self.results["Message"] + if isinstance(text_output, (AIMessage, AIMessageChunk)): artifacts = ChatOutputResponse.from_message( - self._built_object, + text_output, sender=sender, sender_name=sender_name, ) - elif not isinstance(self._built_object, UnbuiltObject): - if isinstance(self._built_object, dict): + elif not isinstance(text_output, UnbuiltObject): + if isinstance(text_output, dict): # Turn the dict into a pleasing to # read JSON inside a code block - message = dict_to_codeblock(self._built_object) - elif isinstance(self._built_object, Record): - message = self._built_object.text + message = dict_to_codeblock(text_output) + elif isinstance(text_output, Record): + message = text_output.text elif isinstance(message, (AsyncIterator, Iterator)): stream_url = self.build_stream_url() message = "" - elif not isinstance(self._built_object, str): - message = str(self._built_object) + self.results["Message"] = message + self.results["Record"].message = message + self._built_object = self.results + elif not isinstance(text_output, str): + message = str(text_output) # if the message is a generator or iterator # it means that it is a stream of messages else: - message = self._built_object + message = text_output artifacts = ChatOutputResponse( message=message, 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 c3faf03a4..eb84557a2 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 @@ -438,7 +438,7 @@ "list": false, "show": true, "multiline": true, - "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(name=\"input_value\", type=str, display_name=\"Message\", multiline=True),\n Input(name=\"sender\", type=str, display_name=\"Sender Type\", options=[\"Machine\", \"AI\"]),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\"),\n Input(name=\"session_id\", type=str, display_name=\"Session ID\"),\n Input(name=\"record_template\", type=str, display_name=\"Record Template\", default=\"{text}\"),\n ]\n outputs = [\n Output(name=\"Message\", method=\"text_response\"),\n Output(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", + "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(name=\"Message\", method=\"text_response\"),\n Output(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", "fileTypes": [], "file_path": "", "password": false, @@ -464,7 +464,7 @@ "display_name": "Message", "advanced": false, "dynamic": false, - "info": "", + "info": "Message to be passed as output.", "load_from_db": false, "title_case": false, "input_types": [ @@ -484,9 +484,9 @@ "password": false, "name": "record_template", "display_name": "Record Template", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", "load_from_db": false, "title_case": false, "input_types": [ @@ -500,19 +500,19 @@ "list": false, "show": true, "multiline": false, - "value": "", + "value": "Machine", "fileTypes": [], "file_path": "", "password": false, "options": [ "Machine", - "AI" + "User" ], "name": "sender", "display_name": "Sender Type", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Type of sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -526,7 +526,7 @@ "list": false, "show": true, "multiline": false, - "value": "", + "value": "AI", "fileTypes": [], "file_path": "", "password": false, @@ -534,7 +534,7 @@ "display_name": "Sender Name", "advanced": false, "dynamic": false, - "info": "", + "info": "Name of the sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -554,9 +554,9 @@ "password": false, "name": "session_id", "display_name": "Session ID", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Session ID for the message.", "load_from_db": false, "title_case": false, "input_types": [ @@ -637,7 +637,7 @@ "list": false, "show": true, "multiline": true, - "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(name=\"input_value\", type=str, display_name=\"Message\", multiline=True, input_types=[]),\n Input(name=\"sender\", type=str, display_name=\"Sender Type\", options=[\"Machine\", \"User\"]),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\"),\n Input(name=\"session_id\", type=str, display_name=\"Session ID\"),\n ]\n outputs = [\n Output(name=\"Message\", method=\"text_response\"),\n Output(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", + "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(name=\"Message\", method=\"text_response\"),\n Output(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", "fileTypes": [], "file_path": "", "password": false, @@ -655,7 +655,7 @@ "list": false, "show": true, "multiline": true, - "value": "", + "value": "Hello, world!", "fileTypes": [], "file_path": "", "password": false, @@ -664,7 +664,7 @@ "advanced": false, "input_types": [], "dynamic": false, - "info": "", + "info": "Message to be passed as input.", "load_from_db": false, "title_case": false }, @@ -675,7 +675,7 @@ "list": false, "show": true, "multiline": false, - "value": "", + "value": "User", "fileTypes": [], "file_path": "", "password": false, @@ -685,9 +685,9 @@ ], "name": "sender", "display_name": "Sender Type", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Type of sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -701,7 +701,7 @@ "list": false, "show": true, "multiline": false, - "value": "", + "value": "User", "fileTypes": [], "file_path": "", "password": false, @@ -709,7 +709,7 @@ "display_name": "Sender Name", "advanced": false, "dynamic": false, - "info": "", + "info": "Name of the sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -729,9 +729,9 @@ "password": false, "name": "session_id", "display_name": "Session ID", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Session ID for the message.", "load_from_db": false, "title_case": false, "input_types": [ 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 4dc94331d..67608d40f 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 @@ -298,7 +298,7 @@ "list": false, "show": true, "multiline": true, - "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(name=\"input_value\", type=str, display_name=\"Message\", multiline=True),\n Input(name=\"sender\", type=str, display_name=\"Sender Type\", options=[\"Machine\", \"AI\"]),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\"),\n Input(name=\"session_id\", type=str, display_name=\"Session ID\"),\n Input(name=\"record_template\", type=str, display_name=\"Record Template\", default=\"{text}\"),\n ]\n outputs = [\n Output(name=\"Message\", method=\"text_response\"),\n Output(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", + "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(name=\"Message\", method=\"text_response\"),\n Output(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", "fileTypes": [], "file_path": "", "password": false, @@ -324,7 +324,7 @@ "display_name": "Message", "advanced": false, "dynamic": false, - "info": "", + "info": "Message to be passed as output.", "load_from_db": false, "title_case": false, "input_types": [ @@ -344,9 +344,9 @@ "password": false, "name": "record_template", "display_name": "Record Template", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", "load_from_db": false, "title_case": false, "input_types": [ @@ -366,13 +366,13 @@ "password": false, "options": [ "Machine", - "AI" + "User" ], "name": "sender", "display_name": "Sender Type", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Type of sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -394,7 +394,7 @@ "display_name": "Sender Name", "advanced": false, "dynamic": false, - "info": "", + "info": "Name of the sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -414,9 +414,9 @@ "password": false, "name": "session_id", "display_name": "Session ID", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Session ID for the message.", "load_from_db": false, "title_case": false, "input_types": [ 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 c5938f438..7defd69dc 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 @@ -296,7 +296,7 @@ "list": false, "show": true, "multiline": true, - "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(name=\"input_value\", type=str, display_name=\"Message\", multiline=True, input_types=[]),\n Input(name=\"sender\", type=str, display_name=\"Sender Type\", options=[\"Machine\", \"User\"]),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\"),\n Input(name=\"session_id\", type=str, display_name=\"Session ID\"),\n ]\n outputs = [\n Output(name=\"Message\", method=\"text_response\"),\n Output(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", + "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(name=\"Message\", method=\"text_response\"),\n Output(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", "fileTypes": [], "file_path": "", "password": false, @@ -323,7 +323,7 @@ "advanced": false, "input_types": [], "dynamic": false, - "info": "", + "info": "Message to be passed as input.", "load_from_db": false, "title_case": false }, @@ -344,9 +344,9 @@ ], "name": "sender", "display_name": "Sender Type", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Type of sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -368,7 +368,7 @@ "display_name": "Sender Name", "advanced": false, "dynamic": false, - "info": "", + "info": "Name of the sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -388,9 +388,9 @@ "password": false, "name": "session_id", "display_name": "Session ID", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Session ID for the message.", "load_from_db": false, "title_case": false, "input_types": [ @@ -470,7 +470,7 @@ "list": false, "show": true, "multiline": true, - "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(name=\"input_value\", type=str, display_name=\"Message\", multiline=True),\n Input(name=\"sender\", type=str, display_name=\"Sender Type\", options=[\"Machine\", \"AI\"]),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\"),\n Input(name=\"session_id\", type=str, display_name=\"Session ID\"),\n Input(name=\"record_template\", type=str, display_name=\"Record Template\", default=\"{text}\"),\n ]\n outputs = [\n Output(name=\"Message\", method=\"text_response\"),\n Output(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", + "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(name=\"Message\", method=\"text_response\"),\n Output(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", "fileTypes": [], "file_path": "", "password": false, @@ -496,7 +496,7 @@ "display_name": "Message", "advanced": false, "dynamic": false, - "info": "", + "info": "Message to be passed as output.", "load_from_db": false, "title_case": false, "input_types": [ @@ -516,9 +516,9 @@ "password": false, "name": "record_template", "display_name": "Record Template", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", "load_from_db": false, "title_case": false, "input_types": [ @@ -538,13 +538,13 @@ "password": false, "options": [ "Machine", - "AI" + "User" ], "name": "sender", "display_name": "Sender Type", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Type of sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -566,7 +566,7 @@ "display_name": "Sender Name", "advanced": false, "dynamic": false, - "info": "", + "info": "Name of the sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -586,9 +586,9 @@ "password": false, "name": "session_id", "display_name": "Session ID", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Session ID for the message.", "load_from_db": false, "title_case": false, "input_types": [ @@ -823,7 +823,7 @@ "password": false, "name": "stream", "display_name": "Stream", - "advanced": false, + "advanced": true, "dynamic": false, "info": "Stream the response from the model. Streaming works only in Chat.", "load_from_db": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json index 62b4338d6..c490d8d4c 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 @@ -22,7 +22,7 @@ "list": false, "show": true, "multiline": true, - "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(name=\"input_value\", type=str, display_name=\"Message\", multiline=True, input_types=[]),\n Input(name=\"sender\", type=str, display_name=\"Sender Type\", options=[\"Machine\", \"User\"]),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\"),\n Input(name=\"session_id\", type=str, display_name=\"Session ID\"),\n ]\n outputs = [\n Output(name=\"Message\", method=\"text_response\"),\n Output(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", + "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(name=\"Message\", method=\"text_response\"),\n Output(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", "fileTypes": [], "file_path": "", "password": false, @@ -49,7 +49,7 @@ "advanced": false, "input_types": [], "dynamic": false, - "info": "", + "info": "Message to be passed as input.", "load_from_db": false, "title_case": false }, @@ -70,9 +70,9 @@ ], "name": "sender", "display_name": "Sender Type", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Type of sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -94,7 +94,7 @@ "display_name": "Sender Name", "advanced": false, "dynamic": false, - "info": "", + "info": "Name of the sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -114,9 +114,9 @@ "password": false, "name": "session_id", "display_name": "Session ID", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Session ID for the message.", "load_from_db": false, "title_case": false, "input_types": [ @@ -196,7 +196,7 @@ "list": false, "show": true, "multiline": true, - "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(name=\"input_value\", type=str, display_name=\"Message\", multiline=True),\n Input(name=\"sender\", type=str, display_name=\"Sender Type\", options=[\"Machine\", \"AI\"]),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\"),\n Input(name=\"session_id\", type=str, display_name=\"Session ID\"),\n Input(name=\"record_template\", type=str, display_name=\"Record Template\", default=\"{text}\"),\n ]\n outputs = [\n Output(name=\"Message\", method=\"text_response\"),\n Output(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", + "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(name=\"Message\", method=\"text_response\"),\n Output(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", "fileTypes": [], "file_path": "", "password": false, @@ -222,7 +222,7 @@ "display_name": "Message", "advanced": false, "dynamic": false, - "info": "", + "info": "Message to be passed as output.", "load_from_db": false, "title_case": false, "input_types": [ @@ -242,9 +242,9 @@ "password": false, "name": "record_template", "display_name": "Record Template", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", "load_from_db": false, "title_case": false, "input_types": [ @@ -264,13 +264,13 @@ "password": false, "options": [ "Machine", - "AI" + "User" ], "name": "sender", "display_name": "Sender Type", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Type of sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -292,7 +292,7 @@ "display_name": "Sender Name", "advanced": false, "dynamic": false, - "info": "", + "info": "Name of the sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -312,9 +312,9 @@ "password": false, "name": "session_id", "display_name": "Session ID", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Session ID for the message.", "load_from_db": false, "title_case": false, "input_types": [ 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 85176dd00..4a184529b 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 @@ -276,7 +276,7 @@ "list": false, "show": true, "multiline": true, - "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(name=\"input_value\", type=str, display_name=\"Message\", multiline=True),\n Input(name=\"sender\", type=str, display_name=\"Sender Type\", options=[\"Machine\", \"AI\"]),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\"),\n Input(name=\"session_id\", type=str, display_name=\"Session ID\"),\n Input(name=\"record_template\", type=str, display_name=\"Record Template\", default=\"{text}\"),\n ]\n outputs = [\n Output(name=\"Message\", method=\"text_response\"),\n Output(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", + "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(name=\"Message\", method=\"text_response\"),\n Output(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", "fileTypes": [], "file_path": "", "password": false, @@ -302,7 +302,7 @@ "display_name": "Message", "advanced": false, "dynamic": false, - "info": "", + "info": "Message to be passed as output.", "load_from_db": false, "title_case": false, "input_types": [ @@ -322,9 +322,9 @@ "password": false, "name": "record_template", "display_name": "Record Template", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", "load_from_db": false, "title_case": false, "input_types": [ @@ -344,13 +344,13 @@ "password": false, "options": [ "Machine", - "AI" + "User" ], "name": "sender", "display_name": "Sender Type", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Type of sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -372,7 +372,7 @@ "display_name": "Sender Name", "advanced": false, "dynamic": false, - "info": "", + "info": "Name of the sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -392,9 +392,9 @@ "password": false, "name": "session_id", "display_name": "Session ID", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Session ID for the message.", "load_from_db": false, "title_case": false, "input_types": [ @@ -471,7 +471,7 @@ "list": false, "show": true, "multiline": true, - "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(name=\"input_value\", type=str, display_name=\"Message\", multiline=True),\n Input(name=\"sender\", type=str, display_name=\"Sender Type\", options=[\"Machine\", \"AI\"]),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\"),\n Input(name=\"session_id\", type=str, display_name=\"Session ID\"),\n Input(name=\"record_template\", type=str, display_name=\"Record Template\", default=\"{text}\"),\n ]\n outputs = [\n Output(name=\"Message\", method=\"text_response\"),\n Output(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", + "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(name=\"Message\", method=\"text_response\"),\n Output(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", "fileTypes": [], "file_path": "", "password": false, @@ -497,7 +497,7 @@ "display_name": "Message", "advanced": false, "dynamic": false, - "info": "", + "info": "Message to be passed as output.", "load_from_db": false, "title_case": false, "input_types": [ @@ -517,9 +517,9 @@ "password": false, "name": "record_template", "display_name": "Record Template", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", "load_from_db": false, "title_case": false, "input_types": [ @@ -539,13 +539,13 @@ "password": false, "options": [ "Machine", - "AI" + "User" ], "name": "sender", "display_name": "Sender Type", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Type of sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -567,7 +567,7 @@ "display_name": "Sender Name", "advanced": false, "dynamic": false, - "info": "", + "info": "Name of the sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -587,9 +587,9 @@ "password": false, "name": "session_id", "display_name": "Session ID", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Session ID for the message.", "load_from_db": false, "title_case": false, "input_types": [ 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 510129323..3237ea965 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 @@ -20,7 +20,7 @@ "list": false, "show": true, "multiline": true, - "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(name=\"input_value\", type=str, display_name=\"Message\", multiline=True, input_types=[]),\n Input(name=\"sender\", type=str, display_name=\"Sender Type\", options=[\"Machine\", \"User\"]),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\"),\n Input(name=\"session_id\", type=str, display_name=\"Session ID\"),\n ]\n outputs = [\n Output(name=\"Message\", method=\"text_response\"),\n Output(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", + "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(name=\"Message\", method=\"text_response\"),\n Output(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", "fileTypes": [], "file_path": "", "password": false, @@ -47,7 +47,7 @@ "advanced": false, "input_types": [], "dynamic": false, - "info": "", + "info": "Message to be passed as input.", "load_from_db": false, "title_case": false }, @@ -68,9 +68,9 @@ ], "name": "sender", "display_name": "Sender Type", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Type of sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -92,7 +92,7 @@ "display_name": "Sender Name", "advanced": false, "dynamic": false, - "info": "", + "info": "Name of the sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -112,9 +112,9 @@ "password": false, "name": "session_id", "display_name": "Session ID", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Session ID for the message.", "load_from_db": false, "title_case": false, "input_types": [ @@ -1290,7 +1290,7 @@ "list": false, "show": true, "multiline": true, - "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(name=\"input_value\", type=str, display_name=\"Message\", multiline=True),\n Input(name=\"sender\", type=str, display_name=\"Sender Type\", options=[\"Machine\", \"AI\"]),\n Input(name=\"sender_name\", type=str, display_name=\"Sender Name\"),\n Input(name=\"session_id\", type=str, display_name=\"Session ID\"),\n Input(name=\"record_template\", type=str, display_name=\"Record Template\", default=\"{text}\"),\n ]\n outputs = [\n Output(name=\"Message\", method=\"text_response\"),\n Output(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", + "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(name=\"Message\", method=\"text_response\"),\n Output(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", "fileTypes": [], "file_path": "", "password": false, @@ -1316,7 +1316,7 @@ "display_name": "Message", "advanced": false, "dynamic": false, - "info": "", + "info": "Message to be passed as output.", "load_from_db": false, "title_case": false, "input_types": [ @@ -1336,9 +1336,9 @@ "password": false, "name": "record_template", "display_name": "Record Template", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", "load_from_db": false, "title_case": false, "input_types": [ @@ -1358,13 +1358,13 @@ "password": false, "options": [ "Machine", - "AI" + "User" ], "name": "sender", "display_name": "Sender Type", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Type of sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -1386,7 +1386,7 @@ "display_name": "Sender Name", "advanced": false, "dynamic": false, - "info": "", + "info": "Name of the sender.", "load_from_db": false, "title_case": false, "input_types": [ @@ -1406,9 +1406,9 @@ "password": false, "name": "session_id", "display_name": "Session ID", - "advanced": false, + "advanced": true, "dynamic": false, - "info": "", + "info": "Session ID for the message.", "load_from_db": false, "title_case": false, "input_types": [ diff --git a/src/backend/base/langflow/interface/initialize/loading.py b/src/backend/base/langflow/interface/initialize/loading.py index ad59be14e..ab8c07a2d 100644 --- a/src/backend/base/langflow/interface/initialize/loading.py +++ b/src/backend/base/langflow/interface/initialize/loading.py @@ -1,12 +1,10 @@ import inspect import json import os -from typing import TYPE_CHECKING, Any, Awaitable, Callable, Type +from typing import TYPE_CHECKING, Any, Type import orjson -import yaml from loguru import logger -from pydantic import BaseModel from langflow.custom.eval import eval_custom_component_code from langflow.schema.schema import Record @@ -119,33 +117,10 @@ async def build_component( # Now set the params as attributes of the custom_component custom_component.set_attributes(params) - build_result = {} - if hasattr(custom_component, "outputs"): - for output in custom_component.outputs: - # Build the output if it's connected to some other vertex - # or if it's not connected to any vertex - if not vertex.outgoing_edges or output.name in vertex.edges_source_names: - method: Callable | Awaitable = getattr(custom_component, output.method) - result = method() - # If the method is asynchronous, we need to await it - if inspect.iscoroutinefunction(method): - result = await result - build_result[output.name] = result + build_results = await custom_component.build_results(vertex) custom_repr = custom_component.custom_repr() - # ! Temporary REPR - # Since all are dict, yaml.dump them - if isinstance(build_result, dict): - _build_result = { - key: value.model_dump() if isinstance(value, BaseModel) else value for key, value in build_result.items() - } - custom_repr = yaml.dump(_build_result) - - if custom_repr is None and isinstance(build_result, (dict, Record, str)): - custom_repr = build_result - if not isinstance(custom_repr, str): - custom_repr = str(custom_repr) - return custom_component, build_result, {"repr": custom_repr} + return custom_component, build_results, {"repr": custom_repr} async def build_custom_component(params: dict, custom_component: "CustomComponent"): diff --git a/tests/data/component_multiple_outputs.py b/tests/data/component_multiple_outputs.py index 26fe13acd..6970ab305 100644 --- a/tests/data/component_multiple_outputs.py +++ b/tests/data/component_multiple_outputs.py @@ -1,8 +1,8 @@ -from langflow.custom import CustomComponent +from langflow.custom import Component from langflow.template.field.base import Input, Output -class MultipleOutputsComponent(CustomComponent): +class MultipleOutputsComponent(Component): inputs = [ Input(display_name="Input", name="input", field_type=str), Input(display_name="Number", name="number", field_type=int), diff --git a/tests/data/component_nested_call.py b/tests/data/component_nested_call.py index 204ff169c..0eef5566f 100644 --- a/tests/data/component_nested_call.py +++ b/tests/data/component_nested_call.py @@ -1,9 +1,9 @@ -from langflow.custom import CustomComponent +from langflow.custom import Component from langflow.template.field.base import Input, Output from random import randint -class MultipleOutputsComponent(CustomComponent): +class MultipleOutputsComponent(Component): inputs = [ Input(display_name="Input", name="input", field_type=str), Input(display_name="Number", name="number", field_type=int),