mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-05-21 23:46:50 +00:00
feat: support manual add and edit for memory facts (#1538)
* feat: support manual add and edit for memory facts * fix: restore memory updater save helper * fix: address memory fact review feedback * fix: remove duplicate memory fact edit action * docs: simplify memory fact review setup * docs: relax memory review startup instructions * fix: clear rebase marker in memory settings page * fix: address memory fact review and format issues * fix: address memory fact review feedback * refactor: make memory fact updates explicit patch semantics --------- Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
This commit is contained in:
@@ -5,7 +5,9 @@ from deerflow.agents.memory.updater import (
|
||||
MemoryUpdater,
|
||||
_extract_text,
|
||||
clear_memory_data,
|
||||
create_memory_fact,
|
||||
delete_memory_fact,
|
||||
update_memory_fact,
|
||||
)
|
||||
from deerflow.config.memory_config import MemoryConfig
|
||||
|
||||
@@ -184,6 +186,43 @@ def test_delete_memory_fact_removes_only_matching_fact() -> None:
|
||||
assert [fact["id"] for fact in result["facts"]] == ["fact_keep"]
|
||||
|
||||
|
||||
def test_create_memory_fact_appends_manual_fact() -> None:
|
||||
with (
|
||||
patch("deerflow.agents.memory.updater.get_memory_data", return_value=_make_memory()),
|
||||
patch("deerflow.agents.memory.updater._save_memory_to_file", return_value=True),
|
||||
):
|
||||
result = create_memory_fact(
|
||||
content=" User prefers concise code reviews. ",
|
||||
category="preference",
|
||||
confidence=0.88,
|
||||
)
|
||||
|
||||
assert len(result["facts"]) == 1
|
||||
assert result["facts"][0]["content"] == "User prefers concise code reviews."
|
||||
assert result["facts"][0]["category"] == "preference"
|
||||
assert result["facts"][0]["confidence"] == 0.88
|
||||
assert result["facts"][0]["source"] == "manual"
|
||||
|
||||
|
||||
def test_create_memory_fact_rejects_empty_content() -> None:
|
||||
try:
|
||||
create_memory_fact(content=" ")
|
||||
except ValueError as exc:
|
||||
assert exc.args == ("content",)
|
||||
else:
|
||||
raise AssertionError("Expected ValueError for empty fact content")
|
||||
|
||||
|
||||
def test_create_memory_fact_rejects_invalid_confidence() -> None:
|
||||
for confidence in (-0.1, 1.1, float("nan"), float("inf"), float("-inf")):
|
||||
try:
|
||||
create_memory_fact(content="User likes tests", confidence=confidence)
|
||||
except ValueError as exc:
|
||||
assert exc.args == ("confidence",)
|
||||
else:
|
||||
raise AssertionError("Expected ValueError for invalid fact confidence")
|
||||
|
||||
|
||||
def test_delete_memory_fact_raises_for_unknown_id() -> None:
|
||||
with patch("deerflow.agents.memory.updater.get_memory_data", return_value=_make_memory()):
|
||||
try:
|
||||
@@ -194,6 +233,121 @@ def test_delete_memory_fact_raises_for_unknown_id() -> None:
|
||||
raise AssertionError("Expected KeyError for missing fact id")
|
||||
|
||||
|
||||
def test_update_memory_fact_updates_only_matching_fact() -> None:
|
||||
current_memory = _make_memory(
|
||||
facts=[
|
||||
{
|
||||
"id": "fact_keep",
|
||||
"content": "User likes Python",
|
||||
"category": "preference",
|
||||
"confidence": 0.9,
|
||||
"createdAt": "2026-03-18T00:00:00Z",
|
||||
"source": "thread-a",
|
||||
},
|
||||
{
|
||||
"id": "fact_edit",
|
||||
"content": "User prefers tabs",
|
||||
"category": "preference",
|
||||
"confidence": 0.8,
|
||||
"createdAt": "2026-03-18T00:00:00Z",
|
||||
"source": "manual",
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
with (
|
||||
patch("deerflow.agents.memory.updater.get_memory_data", return_value=current_memory),
|
||||
patch("deerflow.agents.memory.updater._save_memory_to_file", return_value=True),
|
||||
):
|
||||
result = update_memory_fact(
|
||||
fact_id="fact_edit",
|
||||
content="User prefers spaces",
|
||||
category="workflow",
|
||||
confidence=0.91,
|
||||
)
|
||||
|
||||
assert result["facts"][0]["content"] == "User likes Python"
|
||||
assert result["facts"][1]["content"] == "User prefers spaces"
|
||||
assert result["facts"][1]["category"] == "workflow"
|
||||
assert result["facts"][1]["confidence"] == 0.91
|
||||
assert result["facts"][1]["createdAt"] == "2026-03-18T00:00:00Z"
|
||||
assert result["facts"][1]["source"] == "manual"
|
||||
|
||||
|
||||
def test_update_memory_fact_preserves_omitted_fields() -> None:
|
||||
current_memory = _make_memory(
|
||||
facts=[
|
||||
{
|
||||
"id": "fact_edit",
|
||||
"content": "User prefers tabs",
|
||||
"category": "preference",
|
||||
"confidence": 0.8,
|
||||
"createdAt": "2026-03-18T00:00:00Z",
|
||||
"source": "manual",
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
with (
|
||||
patch("deerflow.agents.memory.updater.get_memory_data", return_value=current_memory),
|
||||
patch("deerflow.agents.memory.updater._save_memory_to_file", return_value=True),
|
||||
):
|
||||
result = update_memory_fact(
|
||||
fact_id="fact_edit",
|
||||
content="User prefers spaces",
|
||||
)
|
||||
|
||||
assert result["facts"][0]["content"] == "User prefers spaces"
|
||||
assert result["facts"][0]["category"] == "preference"
|
||||
assert result["facts"][0]["confidence"] == 0.8
|
||||
|
||||
|
||||
def test_update_memory_fact_raises_for_unknown_id() -> None:
|
||||
with patch("deerflow.agents.memory.updater.get_memory_data", return_value=_make_memory()):
|
||||
try:
|
||||
update_memory_fact(
|
||||
fact_id="fact_missing",
|
||||
content="User prefers concise code reviews.",
|
||||
category="preference",
|
||||
confidence=0.88,
|
||||
)
|
||||
except KeyError as exc:
|
||||
assert exc.args == ("fact_missing",)
|
||||
else:
|
||||
raise AssertionError("Expected KeyError for missing fact id")
|
||||
|
||||
|
||||
def test_update_memory_fact_rejects_invalid_confidence() -> None:
|
||||
current_memory = _make_memory(
|
||||
facts=[
|
||||
{
|
||||
"id": "fact_edit",
|
||||
"content": "User prefers tabs",
|
||||
"category": "preference",
|
||||
"confidence": 0.8,
|
||||
"createdAt": "2026-03-18T00:00:00Z",
|
||||
"source": "manual",
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
for confidence in (-0.1, 1.1, float("nan"), float("inf"), float("-inf")):
|
||||
with patch(
|
||||
"deerflow.agents.memory.updater.get_memory_data",
|
||||
return_value=current_memory,
|
||||
):
|
||||
try:
|
||||
update_memory_fact(
|
||||
fact_id="fact_edit",
|
||||
content="User prefers spaces",
|
||||
confidence=confidence,
|
||||
)
|
||||
except ValueError as exc:
|
||||
assert exc.args == ("confidence",)
|
||||
else:
|
||||
raise AssertionError("Expected ValueError for invalid fact confidence")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _extract_text — LLM response content normalization
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user