diff --git a/src/backend/base/langflow/base/agents/agent.py b/src/backend/base/langflow/base/agents/agent.py index 69fc0f4c9..f092caf0a 100644 --- a/src/backend/base/langflow/base/agents/agent.py +++ b/src/backend/base/langflow/base/agents/agent.py @@ -14,6 +14,7 @@ from langflow.inputs.inputs import DataInput, InputTypes from langflow.io import BoolInput, HandleInput, IntInput, MessageTextInput from langflow.schema.message import Message from langflow.template import Output +from langflow.utils.constants import MESSAGE_SENDER_AI class LCAgentComponent(Component): @@ -58,7 +59,7 @@ class LCAgentComponent(Component): if isinstance(result, list): result = "\n".join([result_dict["text"] for result_dict in result]) - message = Message(text=result, sender="Machine") + message = Message(text=result, sender=MESSAGE_SENDER_AI) self.status = message return message diff --git a/src/backend/base/langflow/base/agents/crewai/crew.py b/src/backend/base/langflow/base/agents/crewai/crew.py index 4f4a7a567..8326c3965 100644 --- a/src/backend/base/langflow/base/agents/crewai/crew.py +++ b/src/backend/base/langflow/base/agents/crewai/crew.py @@ -9,6 +9,7 @@ from langflow.inputs.inputs import HandleInput, InputTypes from langflow.io import BoolInput, IntInput, Output from langflow.schema.data import Data from langflow.schema.message import Message +from langflow.utils.constants import MESSAGE_SENDER_AI class BaseCrewComponent(Component): @@ -78,6 +79,6 @@ class BaseCrewComponent(Component): async def build_output(self) -> Message: crew = self.build_crew() result = await crew.kickoff_async() - message = Message(text=result, sender="Machine") + message = Message(text=result, sender=MESSAGE_SENDER_AI) self.status = message return message diff --git a/src/backend/base/langflow/base/io/chat.py b/src/backend/base/langflow/base/io/chat.py index 6c1b5a5d3..b9ff4f3d1 100644 --- a/src/backend/base/langflow/base/io/chat.py +++ b/src/backend/base/langflow/base/io/chat.py @@ -5,6 +5,7 @@ from langflow.custom import Component from langflow.memory import store_message from langflow.schema import Data from langflow.schema.message import Message +from langflow.utils.constants import MESSAGE_SENDER_USER, MESSAGE_SENDER_AI class ChatComponent(Component): @@ -19,7 +20,7 @@ class ChatComponent(Component): "multiline": True, }, "sender": { - "options": ["Machine", "User"], + "options": [MESSAGE_SENDER_AI, MESSAGE_SENDER_USER], "display_name": "Sender Type", "advanced": True, }, diff --git a/src/backend/base/langflow/base/memory/memory.py b/src/backend/base/langflow/base/memory/memory.py index ba3735dc5..e55301a5f 100644 --- a/src/backend/base/langflow/base/memory/memory.py +++ b/src/backend/base/langflow/base/memory/memory.py @@ -2,6 +2,7 @@ from typing import Optional from langflow.custom import CustomComponent from langflow.schema import Data +from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER class BaseMemoryComponent(CustomComponent): @@ -13,7 +14,7 @@ class BaseMemoryComponent(CustomComponent): def build_config(self): return { "sender": { - "options": ["Machine", "User", "Machine and User"], + "options": [MESSAGE_SENDER_AI, MESSAGE_SENDER_USER, "Machine and User"], "display_name": "Sender Type", }, "sender_name": {"display_name": "Sender Name", "advanced": True}, diff --git a/src/backend/base/langflow/components/deactivated/Message.py b/src/backend/base/langflow/components/deactivated/Message.py index b5eecf19d..ae9313475 100644 --- a/src/backend/base/langflow/components/deactivated/Message.py +++ b/src/backend/base/langflow/components/deactivated/Message.py @@ -2,6 +2,7 @@ from typing import Optional from langflow.custom import CustomComponent from langflow.schema.message import Message +from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER class MessageComponent(CustomComponent): @@ -12,7 +13,7 @@ class MessageComponent(CustomComponent): def build_config(self): return { "sender": { - "options": ["Machine", "User"], + "options": [MESSAGE_SENDER_AI, MESSAGE_SENDER_USER], "display_name": "Sender Type", }, "sender_name": {"display_name": "Sender Name"}, @@ -26,7 +27,7 @@ class MessageComponent(CustomComponent): def build( self, - sender: str = "User", + sender: str = MESSAGE_SENDER_USER, sender_name: Optional[str] = None, session_id: Optional[str] = None, text: str = "", diff --git a/src/backend/base/langflow/components/helpers/Memory.py b/src/backend/base/langflow/components/helpers/Memory.py index 7c27b23a4..7edcacde4 100644 --- a/src/backend/base/langflow/components/helpers/Memory.py +++ b/src/backend/base/langflow/components/helpers/Memory.py @@ -8,6 +8,8 @@ from langflow.schema.message import Message from langflow.field_typing import BaseChatMemory from langchain.memory import ConversationBufferMemory +from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER + class MemoryComponent(Component): display_name = "Chat Memory" @@ -25,15 +27,15 @@ class MemoryComponent(Component): DropdownInput( name="sender", display_name="Sender Type", - options=["Machine", "User", "Machine and User"], + options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER, "Machine and User"], value="Machine and User", - info="Type of sender.", + info="Filter by sender type.", advanced=True, ), MessageTextInput( name="sender_name", display_name="Sender Name", - info="Name of the sender.", + info="Filter by sender name.", advanced=True, ), IntInput( @@ -46,7 +48,7 @@ class MemoryComponent(Component): MessageTextInput( name="session_id", display_name="Session ID", - info="Session ID of the chat history.", + info="The session ID of the chat. If empty, the current session ID parameter will be used.", advanced=True, ), DropdownInput( @@ -87,14 +89,14 @@ class MemoryComponent(Component): self.memory.session_id = session_id stored = self.memory.messages - if sender: - expected_type = "Machine" if sender == "Machine" else "User" - stored = [m for m in stored if m.type == expected_type] if order == "ASC": stored = stored[::-1] if n_messages: stored = stored[:n_messages] stored = [Message.from_lc_message(m) for m in stored] + if sender: + expected_type = MESSAGE_SENDER_AI if sender == MESSAGE_SENDER_AI else MESSAGE_SENDER_USER + stored = [m for m in stored if m.type == expected_type] else: stored = get_messages( sender=sender, diff --git a/src/backend/base/langflow/components/helpers/StoreMessage.py b/src/backend/base/langflow/components/helpers/StoreMessage.py index 0b0a56148..651110a40 100644 --- a/src/backend/base/langflow/components/helpers/StoreMessage.py +++ b/src/backend/base/langflow/components/helpers/StoreMessage.py @@ -3,6 +3,7 @@ from langflow.inputs import MessageInput, StrInput, HandleInput from langflow.schema.message import Message from langflow.template import Output from langflow.memory import get_messages, store_message +from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_NAME_AI class StoreMessageComponent(Component): @@ -23,16 +24,20 @@ class StoreMessageComponent(Component): name="sender", display_name="Sender", info="The sender of the message.", - value="AI", + value=MESSAGE_SENDER_AI, 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=MESSAGE_SENDER_NAME_AI, + advanced=True, ), StrInput( name="session_id", display_name="Session ID", - info="The session ID of the chat.", + info="The session ID of the chat. If empty, the current session ID parameter will be used.", value="", ), ] diff --git a/src/backend/base/langflow/components/inputs/ChatInput.py b/src/backend/base/langflow/components/inputs/ChatInput.py index cc1328a8b..28aa220a0 100644 --- a/src/backend/base/langflow/components/inputs/ChatInput.py +++ b/src/backend/base/langflow/components/inputs/ChatInput.py @@ -4,6 +4,7 @@ from langflow.inputs import BoolInput from langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output from langflow.memory import store_message from langflow.schema.message import Message +from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER, MESSAGE_SENDER_NAME_USER class ChatInput(ChatComponent): @@ -29,8 +30,8 @@ class ChatInput(ChatComponent): DropdownInput( name="sender", display_name="Sender Type", - options=["Machine", "User"], - value="User", + options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER], + value=MESSAGE_SENDER_USER, info="Type of sender.", advanced=True, ), @@ -38,11 +39,14 @@ class ChatInput(ChatComponent): name="sender_name", display_name="Sender Name", info="Name of the sender.", - value="User", + value=MESSAGE_SENDER_NAME_USER, advanced=True, ), MessageTextInput( - name="session_id", display_name="Session ID", info="Session ID for the message.", advanced=True + name="session_id", + display_name="Session ID", + info="The session ID of the chat. If empty, the current session ID parameter will be used.", + advanced=True, ), FileInput( name="files", diff --git a/src/backend/base/langflow/components/memories/AstraDBChatMemory.py b/src/backend/base/langflow/components/memories/AstraDBChatMemory.py index 15561badb..29f751fe2 100644 --- a/src/backend/base/langflow/components/memories/AstraDBChatMemory.py +++ b/src/backend/base/langflow/components/memories/AstraDBChatMemory.py @@ -37,7 +37,10 @@ class AstraDBChatMemory(LCChatMemoryComponent): advanced=True, ), MessageTextInput( - name="session_id", display_name="Session ID", info="Session ID for the message.", advanced=True + name="session_id", + display_name="Session ID", + info="The session ID of the chat. If empty, the current session ID parameter will be used.", + advanced=True, ), ] diff --git a/src/backend/base/langflow/components/outputs/ChatOutput.py b/src/backend/base/langflow/components/outputs/ChatOutput.py index 22319f60e..45972712c 100644 --- a/src/backend/base/langflow/components/outputs/ChatOutput.py +++ b/src/backend/base/langflow/components/outputs/ChatOutput.py @@ -3,6 +3,7 @@ from langflow.inputs import BoolInput from langflow.io import DropdownInput, MessageTextInput, Output from langflow.memory import store_message from langflow.schema.message import Message +from langflow.utils.constants import MESSAGE_SENDER_NAME_AI, MESSAGE_SENDER_USER, MESSAGE_SENDER_AI class ChatOutput(ChatComponent): @@ -27,16 +28,23 @@ class ChatOutput(ChatComponent): DropdownInput( name="sender", display_name="Sender Type", - options=["Machine", "User"], - value="Machine", + options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER], + value=MESSAGE_SENDER_AI, advanced=True, info="Type of sender.", ), MessageTextInput( - name="sender_name", display_name="Sender Name", info="Name of the sender.", value="AI", advanced=True + name="sender_name", + display_name="Sender Name", + info="Name of the sender.", + value=MESSAGE_SENDER_NAME_AI, + advanced=True, ), MessageTextInput( - name="session_id", display_name="Session ID", info="Session ID for the message.", advanced=True + name="session_id", + display_name="Session ID", + info="The session ID of the chat. If empty, the current session ID parameter will be used.", + advanced=True, ), MessageTextInput( name="data_template", diff --git a/src/backend/base/langflow/schema/data.py b/src/backend/base/langflow/schema/data.py index 122f01507..c6296e59c 100644 --- a/src/backend/base/langflow/schema/data.py +++ b/src/backend/base/langflow/schema/data.py @@ -8,6 +8,8 @@ from langchain_core.prompt_values import ImagePromptValue from langchain_core.prompts.image import ImagePromptTemplate from pydantic import BaseModel, model_serializer, model_validator +from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER + class Data(BaseModel): """ @@ -126,10 +128,10 @@ class Data(BaseModel): # they are: "text", "sender" if not all(key in self.data for key in ["text", "sender"]): raise ValueError(f"Missing required keys ('text', 'sender') in Data: {self.data}") - sender = self.data.get("sender", "Machine") + sender = self.data.get("sender", MESSAGE_SENDER_AI) text = self.data.get("text", "") files = self.data.get("files", []) - if sender == "User": + if sender == MESSAGE_SENDER_USER: if files: contents = [{"type": "text", "text": text}] for file_path in files: diff --git a/src/backend/base/langflow/schema/message.py b/src/backend/base/langflow/schema/message.py index 483315021..4fe3acdff 100644 --- a/src/backend/base/langflow/schema/message.py +++ b/src/backend/base/langflow/schema/message.py @@ -14,6 +14,12 @@ from pydantic import BeforeValidator, ConfigDict, Field, field_serializer, field from langflow.base.prompts.utils import dict_values_to_string from langflow.schema.data import Data from langflow.schema.image import Image, get_file_paths, is_image_file +from langflow.utils.constants import ( + MESSAGE_SENDER_USER, + MESSAGE_SENDER_NAME_USER, + MESSAGE_SENDER_NAME_AI, + MESSAGE_SENDER_AI, +) def _timestamp_to_str(timestamp: datetime) -> str: @@ -91,7 +97,7 @@ class Message(Data): else: text = self.text - if self.sender == "User" or not self.sender: + if self.sender == MESSAGE_SENDER_USER or not self.sender: if self.files: contents = [{"type": "text", "text": text}] contents.extend(self.get_file_content_dicts()) @@ -105,15 +111,19 @@ class Message(Data): @classmethod def from_lc_message(cls, lc_message: BaseMessage) -> "Message": if lc_message.type == "human": - sender = "User" + sender = MESSAGE_SENDER_USER + sender_name = MESSAGE_SENDER_NAME_USER elif lc_message.type == "ai": - sender = "Machine" + sender = MESSAGE_SENDER_AI + sender_name = MESSAGE_SENDER_NAME_AI elif lc_message.type == "system": sender = "System" + sender_name = "System" else: sender = lc_message.type + sender_name = lc_message.type - return cls(text=lc_message.content, sender=sender, sender_name=sender) + return cls(text=lc_message.content, sender=sender, sender_name=sender_name) @classmethod def from_data(cls, data: "Data") -> "Message": diff --git a/src/backend/base/langflow/utils/constants.py b/src/backend/base/langflow/utils/constants.py index 99ac950d3..0e3777fd8 100644 --- a/src/backend/base/langflow/utils/constants.py +++ b/src/backend/base/langflow/utils/constants.py @@ -177,3 +177,9 @@ LOADERS_INFO: List[Dict[str, Any]] = [ "allowdTypes": ["docx"], }, ] + + +MESSAGE_SENDER_AI = "Machine" +MESSAGE_SENDER_USER = "User" +MESSAGE_SENDER_NAME_AI = "AI" +MESSAGE_SENDER_NAME_USER = "User" diff --git a/src/backend/base/langflow/utils/schemas.py b/src/backend/base/langflow/utils/schemas.py index 344a52632..2689aeb56 100644 --- a/src/backend/base/langflow/utils/schemas.py +++ b/src/backend/base/langflow/utils/schemas.py @@ -6,6 +6,7 @@ from pydantic import BaseModel, field_validator, model_validator from typing_extensions import TypedDict from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES +from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_NAME_AI class File(TypedDict): @@ -20,8 +21,8 @@ class ChatOutputResponse(BaseModel): """Chat output response schema.""" message: Union[str, List[Union[str, Dict]]] - sender: Optional[str] = "Machine" - sender_name: Optional[str] = "AI" + sender: Optional[str] = MESSAGE_SENDER_AI + sender_name: Optional[str] = MESSAGE_SENDER_NAME_AI session_id: Optional[str] = None stream_url: Optional[str] = None component_id: Optional[str] = None @@ -71,8 +72,8 @@ class ChatOutputResponse(BaseModel): def from_message( cls, message: BaseMessage, - sender: Optional[str] = "Machine", - sender_name: Optional[str] = "AI", + sender: Optional[str] = MESSAGE_SENDER_AI, + sender_name: Optional[str] = MESSAGE_SENDER_NAME_AI, ): """Build chat output response from message.""" content = message.content @@ -87,7 +88,7 @@ class ChatOutputResponse(BaseModel): # \n\n -> \n\n # \n -> \n\n - if self.sender != "Machine": + if self.sender != MESSAGE_SENDER_AI: return self # We need to make sure we don't duplicate \n