fix(memory): skip whitespace-only facts in _apply_updates (#3719)

Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>
This commit is contained in:
Yufeng He 2026-06-23 08:34:41 +08:00 committed by GitHub
parent f7f2a500d1
commit 8167275cef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 27 additions and 1 deletions

View file

@ -652,7 +652,12 @@ class MemoryUpdater:
continue
normalized_content = raw_content.strip()
fact_key = _fact_content_key(normalized_content)
if fact_key is not None and fact_key in existing_fact_keys:
if fact_key is None:
# Empty / whitespace-only content: skip it the same way the
# non-string guard above does, instead of appending a blank
# fact that violates the non-empty-content invariant.
continue
if fact_key in existing_fact_keys:
continue
fact_entry = {

View file

@ -78,6 +78,27 @@ def test_apply_updates_skips_existing_duplicate_and_preserves_removals() -> None
assert all(fact["id"] != "fact_remove" for fact in result["facts"])
def test_apply_updates_skips_whitespace_only_facts() -> None:
updater = MemoryUpdater()
current_memory = _make_memory()
update_data = {
"newFacts": [
{"content": " ", "category": "context", "confidence": 0.9},
{"content": "User prefers dark mode", "category": "preference", "confidence": 0.9},
],
}
with patch(
"deerflow.agents.memory.updater.get_memory_config",
return_value=_memory_config(max_facts=100, fact_confidence_threshold=0.7),
):
result = updater._apply_updates(current_memory, update_data, thread_id="thread-ws")
# The whitespace-only fact must not be stored; the real fact still is.
assert [fact["content"] for fact in result["facts"]] == ["User prefers dark mode"]
assert all(fact["content"].strip() for fact in result["facts"])
def test_prepare_update_prompt_preserves_non_ascii_memory_text() -> None:
updater = MemoryUpdater()
current_memory = _make_memory(