mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-07-21 21:48:04 +00:00
fix(memory): filter hide_from_ui HumanMessages from memory builder (#3697)
Middleware-injected hidden messages (TodoMiddleware.todo_reminder, ViewImageMiddleware, p0 DynamicContextMiddleware.__memory) were being fed to the memory-updating LLM as if they were real user input, polluting long-term memory with framework-internal text. The p0 __memory payload could also trigger a self-amplification loop. Fix: skip HumanMessages with additional_kwargs['hide_from_ui'] in filter_messages_for_memory, consistent with the frontend logic. Closes #3695
This commit is contained in:
parent
8167275cef
commit
bf70280319
@ -61,6 +61,13 @@ def filter_messages_for_memory(messages: list[Any]) -> list[Any]:
|
||||
msg_type = getattr(msg, "type", None)
|
||||
|
||||
if msg_type == "human":
|
||||
# Middleware-injected hidden messages (e.g. TodoMiddleware.todo_reminder,
|
||||
# ViewImageMiddleware, p0 DynamicContextMiddleware.__memory) carry
|
||||
# hide_from_ui and must never reach the memory-updating LLM — otherwise
|
||||
# framework-internal text pollutes long-term memory (and the p0 __memory
|
||||
# payload could trigger a self-amplification loop).
|
||||
if getattr(msg, "additional_kwargs", {}).get("hide_from_ui"):
|
||||
continue
|
||||
content_str = extract_message_text(msg)
|
||||
if "<uploaded_files>" in content_str:
|
||||
stripped = _UPLOAD_BLOCK_RE.sub("", content_str).strip()
|
||||
|
||||
@ -133,6 +133,58 @@ class TestFilterMessagesForMemory:
|
||||
assert "/mnt/user-data/uploads/" not in all_content
|
||||
assert "<uploaded_files>" not in all_content
|
||||
|
||||
# --- hide_from_ui messages are excluded ---
|
||||
|
||||
def test_hide_from_ui_human_message_is_excluded(self):
|
||||
"""Middleware-injected hidden HumanMessages (TodoMiddleware.todo_reminder,
|
||||
ViewImageMiddleware, p0 DynamicContextMiddleware.__memory) must never reach
|
||||
the memory-updating LLM."""
|
||||
hidden_reminder = HumanMessage(
|
||||
content="<system_reminder>\nYour todo list from earlier is no longer visible.\n</system_reminder>",
|
||||
additional_kwargs={"hide_from_ui": True, "name": "todo_reminder"},
|
||||
)
|
||||
msgs = [
|
||||
_human("What is the capital of France?"),
|
||||
_ai("The capital of France is Paris."),
|
||||
hidden_reminder, # should be skipped
|
||||
_ai("Is there anything else I can help with?"), # should be kept
|
||||
]
|
||||
result = filter_messages_for_memory(msgs)
|
||||
|
||||
human_contents = [m.content for m in result if m.type == "human"]
|
||||
assert len(human_contents) == 1
|
||||
assert "What is the capital of France?" in human_contents[0]
|
||||
assert not any("todo list" in c for c in human_contents)
|
||||
assert not any(m.additional_kwargs.get("hide_from_ui") for m in result if m.type == "human")
|
||||
|
||||
def test_p0_memory_payload_is_excluded(self):
|
||||
"""The p0 DynamicContextMiddleware.__memory HumanMessage carries extracted
|
||||
memory facts back to the memory LLM; feeding it again risks a
|
||||
self-amplification loop, so it must be filtered out."""
|
||||
memory_payload = HumanMessage(
|
||||
content="<memory>User prefers concise answers</memory>",
|
||||
additional_kwargs={"hide_from_ui": True},
|
||||
)
|
||||
msgs = [
|
||||
_human("Help me with Python."),
|
||||
_ai("Sure."),
|
||||
memory_payload, # should be skipped
|
||||
]
|
||||
result = filter_messages_for_memory(msgs)
|
||||
|
||||
human_contents = [m.content for m in result if m.type == "human"]
|
||||
assert len(human_contents) == 1
|
||||
assert "Help me with Python." in human_contents[0]
|
||||
assert not any("<memory>" in c for c in human_contents)
|
||||
|
||||
def test_hide_from_ui_false_is_preserved(self):
|
||||
"""Messages without hide_from_ui (or with it set to False) are kept."""
|
||||
visible_msg = HumanMessage(content="Visible message", additional_kwargs={"hide_from_ui": False})
|
||||
msgs = [visible_msg, _ai("Reply.")]
|
||||
result = filter_messages_for_memory(msgs)
|
||||
assert len(result) == 2
|
||||
assert result[0].content == "Visible message"
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# detect_correction
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user