From 898dfab0efdc86f9d3b219a54450d77bbe54ce84 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Fri, 19 Jan 2024 22:11:33 -0300 Subject: [PATCH] Add new IO components for chat input, chat output, message history, and text input --- .../langflow/components/io/ChatInput.py | 21 +++++++ .../langflow/components/io/ChatOutput.py | 39 ++++++++++++ .../langflow/components/io/MessageHistory.py | 59 +++++++++++++++++++ .../langflow/components/io/TextInput.py | 22 +++++++ .../langflow/components/io/__init__.py | 0 5 files changed, 141 insertions(+) create mode 100644 src/backend/langflow/components/io/ChatInput.py create mode 100644 src/backend/langflow/components/io/ChatOutput.py create mode 100644 src/backend/langflow/components/io/MessageHistory.py create mode 100644 src/backend/langflow/components/io/TextInput.py create mode 100644 src/backend/langflow/components/io/__init__.py diff --git a/src/backend/langflow/components/io/ChatInput.py b/src/backend/langflow/components/io/ChatInput.py new file mode 100644 index 000000000..42adc0957 --- /dev/null +++ b/src/backend/langflow/components/io/ChatInput.py @@ -0,0 +1,21 @@ +from typing import Optional + +from langflow import CustomComponent +from langflow.field_typing import Text + + +class ChatInput(CustomComponent): + display_name = "Chat Input" + description = "Used to get user input from the chat." + + field_config = { + "code": { + "show": False, + } + } + + def build(self, message: Optional[str] = None) -> Text: + self.repr_value = message + if not message: + message = "" + return message diff --git a/src/backend/langflow/components/io/ChatOutput.py b/src/backend/langflow/components/io/ChatOutput.py new file mode 100644 index 000000000..b37e754b4 --- /dev/null +++ b/src/backend/langflow/components/io/ChatOutput.py @@ -0,0 +1,39 @@ +from typing import Optional + +from langflow import CustomComponent +from langflow.field_typing import Text + + +class ChatOutput(CustomComponent): + display_name = "Chat Output" + description = "Used to send a message to the chat." + + field_config = { + "code": { + "show": True, + } + } + + def build_config(self): + return { + "message": {"input_types": ["Text"]}, + "sender": {"options": ["Machine", "User"], "display_name": "Sender Type"}, + "sender_name": {"display_name": "Sender Name"}, + "session_id": { + "display_name": "Session ID", + "info": "Session ID of the chat history.", + "input_types": ["Text"], + }, + } + + def build( + self, + sender: Optional[str] = "Machine", + sender_name: Optional[str] = "AI", + session_id: Optional[str] = None, + message: Optional[str] = None, + ) -> Text: + self.repr_value = message + if not message: + message = "" + return message diff --git a/src/backend/langflow/components/io/MessageHistory.py b/src/backend/langflow/components/io/MessageHistory.py new file mode 100644 index 000000000..a9d16a65c --- /dev/null +++ b/src/backend/langflow/components/io/MessageHistory.py @@ -0,0 +1,59 @@ +from typing import List, Optional + +from langchain.schema import Document +from langflow import CustomComponent +from langflow.services.deps import get_monitor_service + + +class MessageHistoryComponent(CustomComponent): + display_name = "Message History" + description = "Used to retrieve stored messages." + + def build_config(self): + return { + "sender": {"options": ["Machine", "User"], "display_name": "Sender Type"}, + "sender_name": {"display_name": "Sender Name"}, + "file_path": { + "display_name": "File Path", + "info": "Path of the local JSON file to store the messages. It should be a unique path for each chat history.", + }, + "n_messages": { + "display_name": "Number of Messages", + "info": "Number of messages to retrieve.", + }, + "session_id": { + "display_name": "Session ID", + "info": "Session ID of the chat history.", + "input_types": ["Text"], + }, + } + + def build( + self, + sender: Optional[str] = None, + sender_name: Optional[str] = None, + session_id: Optional[str] = None, + n_messages: int = 5, + ) -> List[Document]: + # Load the chat history df + monitor_service = get_monitor_service() + chat_history_df = monitor_service.to_df("messages") + + # Filter the df + if session_id: + chat_history_df = chat_history_df[chat_history_df["session_id"] == session_id] + if sender: + chat_history_df = chat_history_df[chat_history_df["sender_type"] == sender] + if sender_name: + chat_history_df = chat_history_df[chat_history_df["sender_name"] == sender_name] + # Sort the df + chat_history_df = chat_history_df.sort_values(by="timestamp") + # Get the last n messages + if n_messages: + chat_history_df = chat_history_df.tail(n_messages) + # Create a list of messages + messages = [] + for _, row in chat_history_df.iterrows(): + messages.append(Document(page_content=f"{row['sender_name']}: {row['message']}")) + # Return the list of messages + return messages diff --git a/src/backend/langflow/components/io/TextInput.py b/src/backend/langflow/components/io/TextInput.py new file mode 100644 index 000000000..3f0125b1a --- /dev/null +++ b/src/backend/langflow/components/io/TextInput.py @@ -0,0 +1,22 @@ +from typing import Optional + +from langflow import CustomComponent +from langflow.field_typing import Text + + +class TextInput(CustomComponent): + display_name = "Text Input" + description = "Used to pass text input to the next component." + + field_config = { + "code": { + "show": False, + }, + "value": {"display_name": "Value"}, + } + + def build(self, value: Optional[str] = "") -> Text: + self.status = value + if not value: + value = "" + return value diff --git a/src/backend/langflow/components/io/__init__.py b/src/backend/langflow/components/io/__init__.py new file mode 100644 index 000000000..e69de29bb