mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-03 06:12:14 +08:00
138 lines
4.8 KiB
Python
138 lines
4.8 KiB
Python
|
|
from unittest.mock import patch
|
||
|
|
|
||
|
|
from deerflow.agents.memory.updater import MemoryUpdater
|
||
|
|
from deerflow.config.memory_config import MemoryConfig
|
||
|
|
|
||
|
|
|
||
|
|
def _make_memory(facts: list[dict[str, object]] | None = None) -> dict[str, object]:
|
||
|
|
return {
|
||
|
|
"version": "1.0",
|
||
|
|
"lastUpdated": "",
|
||
|
|
"user": {
|
||
|
|
"workContext": {"summary": "", "updatedAt": ""},
|
||
|
|
"personalContext": {"summary": "", "updatedAt": ""},
|
||
|
|
"topOfMind": {"summary": "", "updatedAt": ""},
|
||
|
|
},
|
||
|
|
"history": {
|
||
|
|
"recentMonths": {"summary": "", "updatedAt": ""},
|
||
|
|
"earlierContext": {"summary": "", "updatedAt": ""},
|
||
|
|
"longTermBackground": {"summary": "", "updatedAt": ""},
|
||
|
|
},
|
||
|
|
"facts": facts or [],
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
def _memory_config(**overrides: object) -> MemoryConfig:
|
||
|
|
config = MemoryConfig()
|
||
|
|
for key, value in overrides.items():
|
||
|
|
setattr(config, key, value)
|
||
|
|
return config
|
||
|
|
|
||
|
|
|
||
|
|
def test_apply_updates_skips_existing_duplicate_and_preserves_removals() -> None:
|
||
|
|
updater = MemoryUpdater()
|
||
|
|
current_memory = _make_memory(
|
||
|
|
facts=[
|
||
|
|
{
|
||
|
|
"id": "fact_existing",
|
||
|
|
"content": "User likes Python",
|
||
|
|
"category": "preference",
|
||
|
|
"confidence": 0.9,
|
||
|
|
"createdAt": "2026-03-18T00:00:00Z",
|
||
|
|
"source": "thread-a",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "fact_remove",
|
||
|
|
"content": "Old context to remove",
|
||
|
|
"category": "context",
|
||
|
|
"confidence": 0.8,
|
||
|
|
"createdAt": "2026-03-18T00:00:00Z",
|
||
|
|
"source": "thread-a",
|
||
|
|
},
|
||
|
|
]
|
||
|
|
)
|
||
|
|
update_data = {
|
||
|
|
"factsToRemove": ["fact_remove"],
|
||
|
|
"newFacts": [
|
||
|
|
{"content": "User likes Python", "category": "preference", "confidence": 0.95},
|
||
|
|
],
|
||
|
|
}
|
||
|
|
|
||
|
|
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-b")
|
||
|
|
|
||
|
|
assert [fact["content"] for fact in result["facts"]] == ["User likes Python"]
|
||
|
|
assert all(fact["id"] != "fact_remove" for fact in result["facts"])
|
||
|
|
|
||
|
|
|
||
|
|
def test_apply_updates_skips_same_batch_duplicates_and_keeps_source_metadata() -> None:
|
||
|
|
updater = MemoryUpdater()
|
||
|
|
current_memory = _make_memory()
|
||
|
|
update_data = {
|
||
|
|
"newFacts": [
|
||
|
|
{"content": "User prefers dark mode", "category": "preference", "confidence": 0.91},
|
||
|
|
{"content": "User prefers dark mode", "category": "preference", "confidence": 0.92},
|
||
|
|
{"content": "User works on DeerFlow", "category": "context", "confidence": 0.87},
|
||
|
|
],
|
||
|
|
}
|
||
|
|
|
||
|
|
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-42")
|
||
|
|
|
||
|
|
assert [fact["content"] for fact in result["facts"]] == [
|
||
|
|
"User prefers dark mode",
|
||
|
|
"User works on DeerFlow",
|
||
|
|
]
|
||
|
|
assert all(fact["id"].startswith("fact_") for fact in result["facts"])
|
||
|
|
assert all(fact["source"] == "thread-42" for fact in result["facts"])
|
||
|
|
|
||
|
|
|
||
|
|
def test_apply_updates_preserves_threshold_and_max_facts_trimming() -> None:
|
||
|
|
updater = MemoryUpdater()
|
||
|
|
current_memory = _make_memory(
|
||
|
|
facts=[
|
||
|
|
{
|
||
|
|
"id": "fact_python",
|
||
|
|
"content": "User likes Python",
|
||
|
|
"category": "preference",
|
||
|
|
"confidence": 0.95,
|
||
|
|
"createdAt": "2026-03-18T00:00:00Z",
|
||
|
|
"source": "thread-a",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "fact_dark_mode",
|
||
|
|
"content": "User prefers dark mode",
|
||
|
|
"category": "preference",
|
||
|
|
"confidence": 0.8,
|
||
|
|
"createdAt": "2026-03-18T00:00:00Z",
|
||
|
|
"source": "thread-a",
|
||
|
|
},
|
||
|
|
]
|
||
|
|
)
|
||
|
|
update_data = {
|
||
|
|
"newFacts": [
|
||
|
|
{"content": "User prefers dark mode", "category": "preference", "confidence": 0.9},
|
||
|
|
{"content": "User uses uv", "category": "context", "confidence": 0.85},
|
||
|
|
{"content": "User likes noisy logs", "category": "behavior", "confidence": 0.6},
|
||
|
|
],
|
||
|
|
}
|
||
|
|
|
||
|
|
with patch(
|
||
|
|
"deerflow.agents.memory.updater.get_memory_config",
|
||
|
|
return_value=_memory_config(max_facts=2, fact_confidence_threshold=0.7),
|
||
|
|
):
|
||
|
|
result = updater._apply_updates(current_memory, update_data, thread_id="thread-9")
|
||
|
|
|
||
|
|
assert [fact["content"] for fact in result["facts"]] == [
|
||
|
|
"User likes Python",
|
||
|
|
"User uses uv",
|
||
|
|
]
|
||
|
|
assert all(fact["content"] != "User likes noisy logs" for fact in result["facts"])
|
||
|
|
assert result["facts"][1]["source"] == "thread-9"
|