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

@ -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"),
]