feat: combine chat history and chat store into a CRUD component (#8323)

* combine history and store

* combine history and store

* [autofix.ci] apply automated fixes

* Update memory.py

* [autofix.ci] apply automated fixes

* update json

* Update memory.py

* Update memory.py

* [autofix.ci] apply automated fixes

* change order

* change order

* put retrieve first

* add json

* [autofix.ci] apply automated fixes

* Update memory.py

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* update test

* fix test

* update tests

* update memory_chatbot

* change number back

* fix py test

* update

* update pokedex

* update flow

* [autofix.ci] apply automated fixes

* update type converter

* format

* fix name

* update meeting summary

* [autofix.ci] apply automated fixes

* fix test memory chatbot

* update method

* update method

* fix sort

* fix test graph state

* fix test

* fix locator

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Edwin Jose <edwin.jose@datastax.com>
Co-authored-by: Eric Hare <ericrhare@gmail.com>
This commit is contained in:
Yuqi Tang 2025-06-05 15:19:01 -07:00 committed by GitHub
commit e23e543b60
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 7341 additions and 4739 deletions

File diff suppressed because one or more lines are too long

View file

@ -1,28 +1,50 @@
from typing import cast
from typing import Any, cast
from langflow.custom import Component
from langflow.helpers.data import data_to_text
from langflow.inputs import HandleInput
from langflow.io import DropdownInput, IntInput, MessageTextInput, MultilineInput, Output
from langflow.memory import aget_messages
from langflow.schema import Data
from langflow.io import DropdownInput, IntInput, MessageTextInput, MultilineInput, Output, TabInput
from langflow.memory import aget_messages, astore_message
from langflow.schema import Data, dotdict
from langflow.schema.dataframe import DataFrame
from langflow.schema.message import Message
from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER
from langflow.utils.component_utils import set_current_fields, set_field_display
from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_NAME_AI, MESSAGE_SENDER_USER
class MemoryComponent(Component):
display_name = "Message History"
description = "Retrieves stored chat messages from Langflow tables or an external memory."
description = "Stores or retrieves stored chat messages from Langflow tables or an external memory."
icon = "message-square-more"
name = "Memory"
default_keys = ["mode", "memory"]
mode_config = {
"Store": ["message", "memory", "sender", "sender_name", "session_id"],
"Retrieve": ["n_messages", "order", "template", "memory"],
}
inputs = [
TabInput(
name="mode",
display_name="Mode",
options=["Retrieve", "Store"],
value="Retrieve",
info="Operation mode: Store messages or Retrieve messages.",
real_time_refresh=True,
),
MessageTextInput(
name="message",
display_name="Message",
info="The chat message to be stored.",
tool_mode=True,
dynamic=True,
show=False,
),
HandleInput(
name="memory",
display_name="External Memory",
input_types=["Memory"],
info="Retrieve messages from an external memory. If empty, it will use the Langflow tables.",
advanced=True,
),
DropdownInput(
name="sender",
@ -37,6 +59,7 @@ class MemoryComponent(Component):
display_name="Sender Name",
info="Filter by sender name.",
advanced=True,
show=False,
),
IntInput(
name="n_messages",
@ -44,6 +67,7 @@ class MemoryComponent(Component):
value=100,
info="Number of messages to retrieve.",
advanced=True,
show=False,
),
MessageTextInput(
name="session_id",
@ -59,6 +83,8 @@ class MemoryComponent(Component):
info="Order of the messages.",
advanced=True,
tool_mode=True,
required=True,
show=False,
),
MultilineInput(
name="template",
@ -67,14 +93,34 @@ class MemoryComponent(Component):
"It can contain the keys {text}, {sender} or any other key in the message data.",
value="{sender_name}: {text}",
advanced=True,
show=False,
),
]
outputs = [
Output(display_name="Data", name="messages", method="retrieve_messages"),
Output(display_name="Message", name="messages_text", method="retrieve_messages_as_text"),
Output(display_name="DataFrame", name="dataframe", method="as_dataframe"),
]
outputs = [Output(display_name="Messages", name="dataframe", method="retrieve_messages_dataframe", dynamic=True)]
def update_outputs(self, frontend_node: dict, field_name: str, field_value: Any) -> dict:
"""Dynamically show only the relevant output based on the selected output type."""
if field_name == "mode":
# Start with empty outputs
frontend_node["outputs"] = []
if field_value == "Store":
frontend_node["outputs"] = [
Output(
display_name="Stored Messages",
name="stored_messages",
method="store_message",
hidden=True,
dynamic=True,
)
]
if field_value == "Retrieve":
frontend_node["outputs"] = [
Output(
display_name="Messages", name="dataframe", method="retrieve_messages_dataframe", dynamic=True
)
]
return frontend_node
async def retrieve_messages(self) -> Data:
sender = self.sender
@ -118,12 +164,7 @@ class MemoryComponent(Component):
self.status = stored
return cast(Data, stored)
async def retrieve_messages_as_text(self) -> Message:
stored_text = data_to_text(self.template, await self.retrieve_messages())
self.status = stored_text
return Message(text=stored_text)
async def as_dataframe(self) -> DataFrame:
async def retrieve_messages_dataframe(self) -> DataFrame:
"""Convert the retrieved messages into a DataFrame.
Returns:
@ -131,3 +172,54 @@ class MemoryComponent(Component):
"""
messages = await self.retrieve_messages()
return DataFrame(messages)
async def store_message(self) -> Message:
message = Message(text=self.message) if isinstance(self.message, str) else self.message
message.session_id = self.session_id or message.session_id
message.sender = self.sender or message.sender or MESSAGE_SENDER_AI
message.sender_name = self.sender_name or message.sender_name or MESSAGE_SENDER_NAME_AI
stored_messages: list[Message] = []
if self.memory:
self.memory.session_id = message.session_id
lc_message = message.to_lc_message()
await self.memory.aadd_messages([lc_message])
stored_messages = await self.memory.aget_messages() or []
stored_messages = [Message.from_lc_message(m) for m in stored_messages] if stored_messages else []
if message.sender:
stored_messages = [m for m in stored_messages if m.sender == message.sender]
else:
await astore_message(message, flow_id=self.graph.flow_id)
stored_messages = (
await aget_messages(
session_id=message.session_id, sender_name=message.sender_name, sender=message.sender
)
or []
)
if not stored_messages:
msg = "No messages were stored. Please ensure that the session ID and sender are properly set."
raise ValueError(msg)
stored_message = stored_messages[0]
self.status = stored_message
return stored_message
def update_build_config(
self,
build_config: dotdict,
field_value: Any, # noqa: ARG002
field_name: str | None = None, # noqa: ARG002
) -> dotdict:
return set_current_fields(
build_config=build_config,
action_fields=self.mode_config,
selected_action=build_config["mode"]["value"],
default_fields=self.default_keys,
func=set_field_display,
)

View file

@ -12,6 +12,7 @@ class MessageStoreComponent(Component):
description = "Stores a chat message or text into Langflow tables or an external memory."
icon = "message-square-text"
name = "StoreMessage"
legacy = True
inputs = [
MessageTextInput(

File diff suppressed because one or more lines are too long

View file

@ -2600,6 +2600,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -2707,7 +2751,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,
@ -3304,6 +3348,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -3411,7 +3499,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,

View file

@ -408,6 +408,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -511,7 +555,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,

View file

@ -1624,6 +1624,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -1716,7 +1760,7 @@
"Descending"
],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": false,

View file

@ -1502,6 +1502,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -1611,7 +1655,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,

View file

@ -1474,6 +1474,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -1566,7 +1610,7 @@
"Descending"
],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": false,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1234,6 +1234,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -1337,7 +1381,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,

View file

@ -1609,6 +1609,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -1713,7 +1757,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"toggle": false,

View file

@ -1916,6 +1916,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -2019,7 +2063,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,

View file

@ -1254,6 +1254,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -1346,7 +1390,7 @@
"Descending"
],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": false,

View file

@ -975,6 +975,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -1067,7 +1111,7 @@
"Descending"
],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": false,

View file

@ -1351,6 +1351,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -1454,7 +1498,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,

View file

@ -617,6 +617,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -709,7 +753,7 @@
"Descending"
],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": false,
@ -1240,6 +1284,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -1332,7 +1420,7 @@
"Descending"
],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": false,
@ -2689,6 +2777,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -2781,7 +2913,7 @@
"Descending"
],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": false,

View file

@ -1533,6 +1533,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -1637,7 +1681,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"toggle": false,

View file

@ -1595,6 +1595,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -1698,7 +1742,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,

View file

@ -1988,6 +1988,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -2091,7 +2135,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,
@ -2687,6 +2731,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -2790,7 +2878,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,
@ -3386,6 +3474,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -3489,7 +3621,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,

View file

@ -1439,6 +1439,50 @@
"type": "other",
"value": ""
},
"message": {
"_input_type": "MessageTextInput",
"advanced": true,
"display_name": "Message",
"dynamic": false,
"info": "The chat message to be stored.",
"input_types": [
"Message"
],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
"name": "message",
"placeholder": "",
"required": false,
"show": true,
"title_case": false,
"tool_mode": true,
"trace_as_input": true,
"trace_as_metadata": true,
"type": "str",
"value": ""
},
"mode": {
"_input_type": "TabInput",
"advanced": true,
"display_name": "Mode",
"dynamic": false,
"info": "Operation mode: Store messages or Retrieve messages.",
"name": "mode",
"options": [
"Retrieve",
"Store"
],
"placeholder": "",
"real_time_refresh": true,
"required": false,
"show": true,
"title_case": false,
"tool_mode": false,
"trace_as_metadata": true,
"type": "tab",
"value": "Store"
},
"model_kwargs": {
"_input_type": "DictInput",
"advanced": true,
@ -1542,7 +1586,7 @@
],
"options_metadata": [],
"placeholder": "",
"required": false,
"required": true,
"show": true,
"title_case": false,
"tool_mode": true,

View file

@ -1,6 +1,7 @@
from langflow.components.helpers.memory import MemoryComponent
from langflow.components.input_output import ChatInput, ChatOutput
from langflow.components.languagemodels import OpenAIModelComponent
from langflow.components.processing.converter import TypeConverterComponent
from langflow.components.prompts import PromptComponent
from langflow.graph import Graph
@ -13,9 +14,13 @@ def memory_chatbot_graph(template: str | None = None):
AI: """
memory_component = MemoryComponent()
chat_input = ChatInput()
type_converter = TypeConverterComponent()
type_converter.set(input_data=memory_component.retrieve_messages_dataframe)
prompt_component = PromptComponent()
prompt_component.set(
template=template, user_message=chat_input.message_response, context=memory_component.retrieve_messages_as_text
template=template,
user_message=chat_input.message_response,
context=type_converter.convert_to_message,
)
openai_component = OpenAIModelComponent()
openai_component.set(input_value=prompt_component.build_prompt)

File diff suppressed because one or more lines are too long

View file

@ -72,15 +72,21 @@ async def consume_and_assert_stream(response, job_id, timeout=30.0):
"Invalid first event. Expected 'vertices_sorted'. Full event stream:\n" + "\n".join(lines)
)
ids = parsed["data"]["ids"]
ids.sort()
assert ids == ["ChatInput-CIGht"], "Invalid ids in first event. Full event stream:\n" + "\n".join(
assert ids == ["ChatInput-vsgM1"], "Invalid ids in first event. Full event stream:\n" + "\n".join(
lines
)
to_run = parsed["data"]["to_run"]
to_run.sort()
assert to_run == ["ChatInput-CIGht", "ChatOutput-QA7ej", "Memory-amN4Z", "Prompt-iWbCC"], (
"Invalid to_run list in first event. Full event stream:\n" + "\n".join(lines)
expected_to_run = [
"ChatInput-vsgM1",
"Prompt-VSSGR",
"TypeConverterComponent-koSIz",
"Memory-8X8Cq",
"ChatOutput-NAw0P",
]
assert set(to_run) == set(expected_to_run), (
"Invalid to_run list in the first event. Full event stream:\n" + "\n".join(lines)
)
first_event_seen = True
# Last event should be end

View file

@ -4,6 +4,7 @@ import pytest
from langflow.components.helpers.memory import MemoryComponent
from langflow.components.input_output import ChatInput, ChatOutput
from langflow.components.languagemodels import OpenAIModelComponent
from langflow.components.processing.converter import TypeConverterComponent
from langflow.components.prompts import PromptComponent
from langflow.graph import Graph
from langflow.graph.graph.constants import Finish
@ -22,9 +23,13 @@ AI: """
memory_component = MemoryComponent(_id="chat_memory")
memory_component.set(session_id=session_id)
chat_input = ChatInput(_id="chat_input")
type_converter = TypeConverterComponent(_id="type_converter")
type_converter.set(input_data=memory_component.retrieve_messages_dataframe)
prompt_component = PromptComponent(_id="prompt")
prompt_component.set(
template=template, user_message=chat_input.message_response, context=memory_component.retrieve_messages_as_text
template=template,
user_message=chat_input.message_response,
context=type_converter.convert_to_message,
)
openai_component = OpenAIModelComponent(_id="openai")
openai_component.set(
@ -44,6 +49,7 @@ AI: """
"chat_output",
"openai",
"prompt",
"type_converter",
"chat_memory",
]

View file

@ -257,8 +257,12 @@ def test_update_source_handle():
async def test_serialize_graph():
# Get the actual starter projects and directly await the result
starter_projects = await load_starter_projects()
data = starter_projects[0][1]["data"]
project_data = starter_projects[0][1]
data = project_data["data"]
# Create and test the graph
graph = Graph.from_payload(data)
assert isinstance(graph, Graph)
serialized = graph.dumps()

View file

@ -6,6 +6,7 @@ import pytest
from langflow.components.helpers.memory import MemoryComponent
from langflow.components.input_output import ChatInput, ChatOutput
from langflow.components.languagemodels import OpenAIModelComponent
from langflow.components.processing.converter import TypeConverterComponent
from langflow.components.prompts import PromptComponent
from langflow.graph import Graph
from langflow.graph.graph.constants import Finish
@ -24,9 +25,13 @@ AI: """
memory_component = MemoryComponent(_id="chat_memory")
memory_component.set(session_id=session_id)
chat_input = ChatInput(_id="chat_input")
type_converter = TypeConverterComponent(_id="type_converter")
type_converter.set(input_data=memory_component.retrieve_messages_dataframe)
prompt_component = PromptComponent(_id="prompt")
prompt_component.set(
template=template, user_message=chat_input.message_response, context=memory_component.retrieve_messages_as_text
template=template,
user_message=chat_input.message_response,
context=type_converter.convert_to_message,
)
openai_component = OpenAIModelComponent(_id="openai")
openai_component.set(
@ -38,22 +43,30 @@ AI: """
chat_output.set(input_value=openai_component.text_response)
graph = Graph(chat_input, chat_output)
assert graph.in_degree_map == {"chat_output": 1, "prompt": 2, "openai": 1, "chat_input": 0, "chat_memory": 0}
assert graph.in_degree_map == {
"chat_output": 1,
"type_converter": 1,
"prompt": 2,
"openai": 1,
"chat_input": 0,
"chat_memory": 0,
}
return graph
@pytest.mark.usefixtures("client")
def test_memory_chatbot(memory_chatbot_graph):
# Now we run step by step
expected_order = deque(["chat_input", "chat_memory", "prompt", "openai", "chat_output"])
expected_order = deque(["chat_input", "chat_memory", "type_converter", "prompt", "openai", "chat_output"])
assert memory_chatbot_graph.in_degree_map == {
"chat_output": 1,
"type_converter": 1,
"prompt": 2,
"openai": 1,
"chat_input": 0,
"chat_memory": 0,
}
assert memory_chatbot_graph.vertices_layers == [["prompt"], ["openai"], ["chat_output"]]
assert memory_chatbot_graph.vertices_layers == [["type_converter"], ["prompt"], ["openai"], ["chat_output"]]
assert memory_chatbot_graph.first_layer == ["chat_input", "chat_memory"]
for step in expected_order:
@ -86,8 +99,8 @@ def test_memory_chatbot_dump_structure(memory_chatbot_graph: Graph):
description = graph_dict["description"]
endpoint_name = graph_dict["endpoint_name"]
assert len(nodes) == 5
assert len(edges) == 4
assert len(nodes) == 6
assert len(edges) == 5
assert description is not None
assert endpoint_name is not None
@ -124,7 +137,8 @@ def test_memory_chatbot_dump_components_and_edges(memory_chatbot_graph: Graph):
# Check edges
expected_edges = [
("chat_input", "prompt"),
("chat_memory", "prompt"),
("chat_memory", "type_converter"),
("type_converter", "prompt"),
("prompt", "openai"),
("openai", "chat_output"),
]

View file

@ -755,6 +755,7 @@
},
"node_modules/@clack/prompts/node_modules/is-unicode-supported": {
"version": "1.3.0",
"extraneous": true,
"inBundle": true,
"license": "MIT",
"engines": {

View file

@ -74,7 +74,6 @@ test(
await expect(page.getByTestId("input_outputChat Input")).toBeVisible();
await expect(page.getByTestId("input_outputChat Output")).toBeVisible();
await expect(page.getByTestId("promptsPrompt")).toBeVisible();
await expect(page.getByTestId("helpersMessage History")).toBeVisible();
await expect(page.getByTestId("langchain_utilitiesCSVAgent")).toBeVisible();
await expect(
page.getByTestId("langchain_utilitiesConversationChain"),
@ -99,7 +98,6 @@ test(
await expect(page.getByTestId("input_outputChat Input")).not.toBeVisible();
await expect(page.getByTestId("input_outputChat Output")).not.toBeVisible();
await expect(page.getByTestId("promptsPrompt")).not.toBeVisible();
await expect(page.getByTestId("helpersMessage History")).not.toBeVisible();
await expect(
page.getByTestId("agentsTool Calling Agent"),
).not.toBeVisible();
@ -121,7 +119,6 @@ test(
await expect(page.getByTestId("disclosure-tools")).toBeVisible();
await expect(page.getByTestId("dataAPI Request")).toBeVisible();
await expect(page.getByTestId("helpersMessage History")).toBeVisible();
await expect(page.getByTestId("vectorstoresAstra DB")).toBeVisible();
await expect(page.getByTestId("logicSub Flow [Deprecated]")).toBeVisible();
@ -138,7 +135,6 @@ test(
await page.getByTestId("icon-X").first().click();
await expect(page.getByTestId("dataAPI Request")).not.toBeVisible();
await expect(page.getByTestId("helpersMessage History")).not.toBeVisible();
await expect(page.getByTestId("vectorstoresAstra DB")).not.toBeVisible();
await expect(
page.getByTestId("logicSub Flow [Deprecated]"),

View file

@ -44,6 +44,7 @@ withEventDeliveryModes(
try {
await page
.getByTestId("anchor-popover-anchor-input-api_key")
.locator("input")
.last()
.fill(process.env.ANTHROPIC_API_KEY ?? "");
} catch (e) {