From b59eb36c3d1cb4b405faae9f346e630814fee445 Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Wed, 26 Jun 2024 11:12:25 -0300 Subject: [PATCH 1/6] Update StoreMessageComponent for enhanced message handling - Changed base class from CustomComponent to Component - Added multiple input fields: message, sender, sender_name, session_id - Included output field for stored messages - Improved logic to handle both string and Message types - Enhanced error handling and validation for message storage --- .../components/helpers/StoreMessage.py | 76 +++++++++++++++---- 1 file changed, 61 insertions(+), 15 deletions(-) diff --git a/src/backend/base/langflow/components/helpers/StoreMessage.py b/src/backend/base/langflow/components/helpers/StoreMessage.py index 5d0abfbb9..6e37573a8 100644 --- a/src/backend/base/langflow/components/helpers/StoreMessage.py +++ b/src/backend/base/langflow/components/helpers/StoreMessage.py @@ -1,22 +1,68 @@ -from langflow.custom import CustomComponent -from langflow.memory import get_messages, store_message +from langflow.custom import Component +from langflow.inputs import MessageTextInput, StrInput from langflow.schema.message import Message +from langflow.template import Output +from langflow.memory import get_messages, store_message - -class StoreMessageComponent(CustomComponent): +class StoreMessageComponent(Component): display_name = "Store Message" - description = "Stores a chat message." + description = "Stores a chat message or text." + icon = "save" - def build_config(self): - return { - "message": {"display_name": "Message"}, - } + inputs = [ + MessageTextInput( + name="message", + display_name="Message", + info="The chat message to be stored.", + input_types=["Message", "str"], + required=True + ), + StrInput( + name="sender", + display_name="Sender", + info="The sender of the message.", + value="", + advanced=True, + ), + StrInput( + name="sender_name", + display_name="Sender Name", + info="The name of the sender.", + value="", + advanced=True + ), + StrInput( + name="session_id", + display_name="Session ID", + info="The session ID of the chat.", + value="", + + ), + ] + + outputs = [ + Output(display_name="Stored Messages", name="stored_messages", method="store_message"), + ] + + def store_message(self) -> Message: + if isinstance(self.message, str): + if not self.session_id: + raise ValueError("If passing a text, Session ID cannot be empty.") + message = Message(text=self.message, sender=self.sender, sender_name=self.sender_name, session_id=self.session_id) + + elif isinstance(self.message, Message): + message = self.message + if self.session_id: + message.session_id = self.session_id + if self.sender: + message.sender = self.sender + if self.sender_name: + message.sender_name = self.sender_name + else: + raise ValueError("Message should be either string or Message.") - def build( - self, - message: Message, - ) -> Message: store_message(message, flow_id=self.graph.flow_id) - self.status = get_messages() - return message + stored = get_messages(session_id=message.session_id, sender_name=message.sender_name, sender=message.sender) + self.status = stored + return stored From acccbee690d39031e1028f8f848d90dddd16905d Mon Sep 17 00:00:00 2001 From: rodrigosnader Date: Wed, 26 Jun 2024 14:13:47 +0000 Subject: [PATCH 2/6] Apply Ruff formatting --- .../langflow/components/helpers/StoreMessage.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/backend/base/langflow/components/helpers/StoreMessage.py b/src/backend/base/langflow/components/helpers/StoreMessage.py index 6e37573a8..4864bf4a7 100644 --- a/src/backend/base/langflow/components/helpers/StoreMessage.py +++ b/src/backend/base/langflow/components/helpers/StoreMessage.py @@ -4,6 +4,7 @@ from langflow.schema.message import Message from langflow.template import Output from langflow.memory import get_messages, store_message + class StoreMessageComponent(Component): display_name = "Store Message" description = "Stores a chat message or text." @@ -15,7 +16,7 @@ class StoreMessageComponent(Component): display_name="Message", info="The chat message to be stored.", input_types=["Message", "str"], - required=True + required=True, ), StrInput( name="sender", @@ -25,18 +26,13 @@ class StoreMessageComponent(Component): advanced=True, ), StrInput( - name="sender_name", - display_name="Sender Name", - info="The name of the sender.", - value="", - advanced=True + name="sender_name", display_name="Sender Name", info="The name of the sender.", value="", advanced=True ), StrInput( name="session_id", display_name="Session ID", info="The session ID of the chat.", value="", - ), ] @@ -48,7 +44,9 @@ class StoreMessageComponent(Component): if isinstance(self.message, str): if not self.session_id: raise ValueError("If passing a text, Session ID cannot be empty.") - message = Message(text=self.message, sender=self.sender, sender_name=self.sender_name, session_id=self.session_id) + message = Message( + text=self.message, sender=self.sender, sender_name=self.sender_name, session_id=self.session_id + ) elif isinstance(self.message, Message): message = self.message From 63dd58c639fa92d9499ebe733ee0a9a0dda0f22a Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Wed, 26 Jun 2024 12:02:18 -0300 Subject: [PATCH 3/6] Update StoreMessageComponent for enhanced message handling --- .../components/helpers/StoreMessage.py | 36 +++++-------- .../langflow/components/prototypes/Pass.py | 54 +++++++++---------- 2 files changed, 40 insertions(+), 50 deletions(-) diff --git a/src/backend/base/langflow/components/helpers/StoreMessage.py b/src/backend/base/langflow/components/helpers/StoreMessage.py index 4864bf4a7..90e2c2769 100644 --- a/src/backend/base/langflow/components/helpers/StoreMessage.py +++ b/src/backend/base/langflow/components/helpers/StoreMessage.py @@ -1,5 +1,5 @@ from langflow.custom import Component -from langflow.inputs import MessageTextInput, StrInput +from langflow.inputs import MessageInput, StrInput from langflow.schema.message import Message from langflow.template import Output from langflow.memory import get_messages, store_message @@ -11,22 +11,25 @@ class StoreMessageComponent(Component): icon = "save" inputs = [ - MessageTextInput( + MessageInput( name="message", display_name="Message", info="The chat message to be stored.", - input_types=["Message", "str"], - required=True, + required=True ), StrInput( name="sender", display_name="Sender", info="The sender of the message.", - value="", + value="AI", advanced=True, ), StrInput( - name="sender_name", display_name="Sender Name", info="The name of the sender.", value="", advanced=True + name="sender_name", + display_name="Sender Name", + info="The name of the sender.", + value="AI", + advanced=True ), StrInput( name="session_id", @@ -41,26 +44,13 @@ class StoreMessageComponent(Component): ] def store_message(self) -> Message: - if isinstance(self.message, str): - if not self.session_id: - raise ValueError("If passing a text, Session ID cannot be empty.") - message = Message( - text=self.message, sender=self.sender, sender_name=self.sender_name, session_id=self.session_id - ) + message = self.message - elif isinstance(self.message, Message): - message = self.message - if self.session_id: - message.session_id = self.session_id - if self.sender: - message.sender = self.sender - if self.sender_name: - message.sender_name = self.sender_name - else: - raise ValueError("Message should be either string or Message.") + message.session_id = self.session_id or message.session_id + message.sender = self.sender or message.sender + message.sender_name = self.sender_name or message.sender_name store_message(message, flow_id=self.graph.flow_id) - stored = get_messages(session_id=message.session_id, sender_name=message.sender_name, sender=message.sender) self.status = stored return stored diff --git a/src/backend/base/langflow/components/prototypes/Pass.py b/src/backend/base/langflow/components/prototypes/Pass.py index 4e2f234c9..a84164380 100644 --- a/src/backend/base/langflow/components/prototypes/Pass.py +++ b/src/backend/base/langflow/components/prototypes/Pass.py @@ -1,31 +1,31 @@ -from typing import Union +from langflow.custom import Component +from langflow.io import MessageInput +from langflow.schema.message import Message +from langflow.template import Output -from langflow.custom import CustomComponent -from langflow.field_typing import Text -from langflow.schema import Data - - -class PassComponent(CustomComponent): +class PassMessageComponent(Component): display_name = "Pass" - description = "A pass-through component that forwards the second input while ignoring the first, used for controlling workflow direction." - field_order = ["ignored_input", "forwarded_input"] - beta = True + description = "Forwards the input message, unchanged." + icon = "arrow-right" - def build_config(self) -> dict: - return { - "ignored_input": { - "display_name": "Ignored Input", - "info": "This input is ignored. It's used to control the flow in the graph.", - "input_types": ["Text", "Data"], - }, - "forwarded_input": { - "display_name": "Input", - "info": "This input is forwarded by the component.", - "input_types": ["Text", "Data"], - }, - } + inputs = [ + MessageInput( + name="input_message", + display_name="Input Message", + info="The message to be passed forward.", + ), + MessageInput( + name="ignored_message", + display_name="Ignored Message", + info="A second message to be ignored. Used as a workaround for continuity.", + advanced=True + ), + ] - def build(self, ignored_input: Text, forwarded_input: Text) -> Union[Text, Data]: - # The ignored_input is not used in the logic, it's just there for graph flow control - self.status = forwarded_input - return forwarded_input + outputs = [ + Output(display_name="Output Message", name="output_message", method="pass_message"), + ] + + def pass_message(self) -> Message: + self.status = self.input_message + return self.input_message From ec36acdff215d3ea3c0af006d16801d465680aa5 Mon Sep 17 00:00:00 2001 From: rodrigosnader Date: Wed, 26 Jun 2024 15:03:14 +0000 Subject: [PATCH 4/6] Apply Ruff formatting --- .../langflow/components/helpers/StoreMessage.py | 13 ++----------- .../base/langflow/components/prototypes/Pass.py | 3 ++- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/backend/base/langflow/components/helpers/StoreMessage.py b/src/backend/base/langflow/components/helpers/StoreMessage.py index 90e2c2769..ce1abbe29 100644 --- a/src/backend/base/langflow/components/helpers/StoreMessage.py +++ b/src/backend/base/langflow/components/helpers/StoreMessage.py @@ -11,12 +11,7 @@ class StoreMessageComponent(Component): icon = "save" inputs = [ - MessageInput( - name="message", - display_name="Message", - info="The chat message to be stored.", - required=True - ), + MessageInput(name="message", display_name="Message", info="The chat message to be stored.", required=True), StrInput( name="sender", display_name="Sender", @@ -25,11 +20,7 @@ class StoreMessageComponent(Component): advanced=True, ), StrInput( - name="sender_name", - display_name="Sender Name", - info="The name of the sender.", - value="AI", - advanced=True + name="sender_name", display_name="Sender Name", info="The name of the sender.", value="AI", advanced=True ), StrInput( name="session_id", diff --git a/src/backend/base/langflow/components/prototypes/Pass.py b/src/backend/base/langflow/components/prototypes/Pass.py index a84164380..28e9ea524 100644 --- a/src/backend/base/langflow/components/prototypes/Pass.py +++ b/src/backend/base/langflow/components/prototypes/Pass.py @@ -3,6 +3,7 @@ from langflow.io import MessageInput from langflow.schema.message import Message from langflow.template import Output + class PassMessageComponent(Component): display_name = "Pass" description = "Forwards the input message, unchanged." @@ -18,7 +19,7 @@ class PassMessageComponent(Component): name="ignored_message", display_name="Ignored Message", info="A second message to be ignored. Used as a workaround for continuity.", - advanced=True + advanced=True, ), ] From 513f157a1b6b220a114dc45032eb6ee391266dae Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Fri, 28 Jun 2024 11:02:24 -0300 Subject: [PATCH 5/6] feat: Add CreateListComponent for creating a list of texts This commit adds a new component called CreateListComponent, which is responsible for creating a list of texts. The component takes in one or more texts as input and outputs a list of Data objects. This component is useful for scenarios where a list of texts needs to be processed or manipulated. The CreateListComponent class is added to the helpers module in the langflow.components package. It includes the necessary inputs and outputs, as well as a create_list method that generates the list of Data objects based on the input texts. This commit also includes some minor changes to other files, such as renaming the UUIDGeneratorComponent to IDGeneratorComponent and updating import statements. --- .../langflow/components/helpers/CreateList.py | 27 +++++++++++++++++++ .../components/helpers/IDGenerator.py | 2 +- .../langflow/components/helpers/__init__.py | 7 +++-- .../prototypes/ConditionalRouter.py | 16 +++++------ .../langflow/components/prototypes/Pass.py | 3 +-- tests/unit/test_helper_components.py | 2 +- 6 files changed, 41 insertions(+), 16 deletions(-) create mode 100644 src/backend/base/langflow/components/helpers/CreateList.py diff --git a/src/backend/base/langflow/components/helpers/CreateList.py b/src/backend/base/langflow/components/helpers/CreateList.py new file mode 100644 index 000000000..217e16dfe --- /dev/null +++ b/src/backend/base/langflow/components/helpers/CreateList.py @@ -0,0 +1,27 @@ +from langflow.custom import Component +from langflow.inputs import StrInput +from langflow.schema import Data +from langflow.template import Output + +class CreateListComponent(Component): + display_name = "Create List" + description = "Creates a list of texts." + icon = "list" + + inputs = [ + StrInput( + name="texts", + display_name="Texts", + info="Enter one or more texts.", + is_list=True, + ), + ] + + outputs = [ + Output(display_name="Data List", name="list", method="create_list"), + ] + + def create_list(self) -> list[Data]: + data = [Data(text=text) for text in self.texts] + self.status = data + return data diff --git a/src/backend/base/langflow/components/helpers/IDGenerator.py b/src/backend/base/langflow/components/helpers/IDGenerator.py index 72a944f71..7e63f870b 100644 --- a/src/backend/base/langflow/components/helpers/IDGenerator.py +++ b/src/backend/base/langflow/components/helpers/IDGenerator.py @@ -5,7 +5,7 @@ from langflow.custom import CustomComponent from langflow.schema.dotdict import dotdict -class UUIDGeneratorComponent(CustomComponent): +class IDGeneratorComponent(CustomComponent): display_name = "ID Generator" description = "Generates a unique ID." diff --git a/src/backend/base/langflow/components/helpers/__init__.py b/src/backend/base/langflow/components/helpers/__init__.py index 1941e38b8..fcc9e83ee 100644 --- a/src/backend/base/langflow/components/helpers/__init__.py +++ b/src/backend/base/langflow/components/helpers/__init__.py @@ -1,22 +1,25 @@ from .CombineText import CombineTextComponent from .CustomComponent import CustomComponent from .FilterData import FilterDataComponent -from .IDGenerator import UUIDGeneratorComponent +from .IDGenerator import IDGeneratorComponent from .Memory import MemoryComponent from .MergeData import MergeDataComponent from .ParseData import ParseDataComponent from .SplitText import SplitTextComponent from .StoreMessage import StoreMessageComponent +from .CreateList import CreateListComponent __all__ = [ + "CreateListComponent", "CombineTextComponent", "CustomComponent", "FilterDataComponent", - "UUIDGeneratorComponent", + "IDGeneratorComponent", "MemoryComponent", "MergeDataComponent", "ParseDataComponent", "SplitTextComponent", "StoreMessageComponent", + "ListComponent", ] diff --git a/src/backend/base/langflow/components/prototypes/ConditionalRouter.py b/src/backend/base/langflow/components/prototypes/ConditionalRouter.py index 8305730ba..07c8103f0 100644 --- a/src/backend/base/langflow/components/prototypes/ConditionalRouter.py +++ b/src/backend/base/langflow/components/prototypes/ConditionalRouter.py @@ -66,21 +66,17 @@ class ConditionalRouterComponent(Component): def true_response(self) -> Message: result = self.evaluate_condition(self.input_text, self.match_text, self.operator, self.case_sensitive) if result: - self.stop("false_result") - response = self.message if self.message else self.input_text - self.status = response - return response + self.status = self.message + return self.message else: self.stop("true_result") - return Message() + return None def false_response(self) -> Message: result = self.evaluate_condition(self.input_text, self.match_text, self.operator, self.case_sensitive) if not result: - self.stop("true_result") - response = self.message if self.message else self.input_text - self.status = response - return response + self.status = self.message + return self.message else: self.stop("false_result") - return Message() + return None diff --git a/src/backend/base/langflow/components/prototypes/Pass.py b/src/backend/base/langflow/components/prototypes/Pass.py index 28e9ea524..a84164380 100644 --- a/src/backend/base/langflow/components/prototypes/Pass.py +++ b/src/backend/base/langflow/components/prototypes/Pass.py @@ -3,7 +3,6 @@ from langflow.io import MessageInput from langflow.schema.message import Message from langflow.template import Output - class PassMessageComponent(Component): display_name = "Pass" description = "Forwards the input message, unchanged." @@ -19,7 +18,7 @@ class PassMessageComponent(Component): name="ignored_message", display_name="Ignored Message", info="A second message to be ignored. Used as a workaround for continuity.", - advanced=True, + advanced=True ), ] diff --git a/tests/unit/test_helper_components.py b/tests/unit/test_helper_components.py index 9e9c4f63a..dc07c5835 100644 --- a/tests/unit/test_helper_components.py +++ b/tests/unit/test_helper_components.py @@ -31,7 +31,7 @@ from langflow.schema import Data def test_uuid_generator_component(): # Arrange - uuid_generator_component = helpers.UUIDGeneratorComponent() + uuid_generator_component = helpers.IDGeneratorComponent() uuid_generator_component.code = open(helpers.IDGenerator.__file__, "r").read() frontend_node, _ = build_custom_component_template(uuid_generator_component) From 93b97fba616d3ae16696385ece380ba4c13ab521 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:03:06 +0000 Subject: [PATCH 6/6] [autofix.ci] apply automated fixes --- src/backend/base/langflow/components/helpers/CreateList.py | 1 + src/backend/base/langflow/components/prototypes/Pass.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/base/langflow/components/helpers/CreateList.py b/src/backend/base/langflow/components/helpers/CreateList.py index 217e16dfe..ea0130ecc 100644 --- a/src/backend/base/langflow/components/helpers/CreateList.py +++ b/src/backend/base/langflow/components/helpers/CreateList.py @@ -3,6 +3,7 @@ from langflow.inputs import StrInput from langflow.schema import Data from langflow.template import Output + class CreateListComponent(Component): display_name = "Create List" description = "Creates a list of texts." diff --git a/src/backend/base/langflow/components/prototypes/Pass.py b/src/backend/base/langflow/components/prototypes/Pass.py index a84164380..28e9ea524 100644 --- a/src/backend/base/langflow/components/prototypes/Pass.py +++ b/src/backend/base/langflow/components/prototypes/Pass.py @@ -3,6 +3,7 @@ from langflow.io import MessageInput from langflow.schema.message import Message from langflow.template import Output + class PassMessageComponent(Component): display_name = "Pass" description = "Forwards the input message, unchanged." @@ -18,7 +19,7 @@ class PassMessageComponent(Component): name="ignored_message", display_name="Ignored Message", info="A second message to be ignored. Used as a workaround for continuity.", - advanced=True + advanced=True, ), ]