mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-11-13 06:31:47 +00:00
* feat(projects): add visible project memory with extraction controls * fix(projects): avoid replaying committed memory extractions * chore(ci): retrigger project memory checks --------- Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
59 lines
2.5 KiB
Python
59 lines
2.5 KiB
Python
"""Every project-memory route offloads its synchronous repository work."""
|
|
|
|
import asyncio
|
|
import threading
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
import test_project_memory as memory_tests
|
|
from _router_auth_helpers import call_unwrapped
|
|
|
|
from app.gateway.routers import projects
|
|
from deerflow.config.projects_config import ProjectsConfig
|
|
|
|
|
|
@pytest.fixture
|
|
def repo(tmp_path):
|
|
yield from memory_tests.repo.__wrapped__(tmp_path)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("operation", ["get", "set_enabled", "delete", "promote"])
|
|
async def test_memory_routes_keep_repository_io_off_the_loop(repo, tmp_path, monkeypatch, operation):
|
|
await asyncio.to_thread(repo.apply, "p1", "u1", "t1", 0, {"newFacts": [memory_tests.fact()]})
|
|
state = await asyncio.to_thread(repo.get, "p1", "u1")
|
|
fact_id = state["facts"][0]["id"]
|
|
marker = tmp_path / "repository-io.txt"
|
|
await asyncio.to_thread(marker.write_text, "worker read", encoding="utf-8")
|
|
loop_thread = threading.get_ident()
|
|
original = getattr(repo, operation)
|
|
calls = []
|
|
|
|
def observed(*args, **kwargs):
|
|
# The strict detector catches this real read if either offload is removed.
|
|
assert marker.read_text(encoding="utf-8") == "worker read"
|
|
assert threading.get_ident() != loop_thread
|
|
calls.append(args)
|
|
return original(*args, **kwargs)
|
|
|
|
monkeypatch.setattr(repo, operation, observed)
|
|
monkeypatch.setattr(projects, "get_project_memory_repository", lambda: repo)
|
|
monkeypatch.setattr(projects, "get_effective_user_id", lambda: "u1")
|
|
monkeypatch.setattr(projects, "_projects_config", ProjectsConfig)
|
|
request = SimpleNamespace()
|
|
if operation == "get":
|
|
result = await call_unwrapped(projects.get_project_memory, "p1", request)
|
|
assert result.facts[0].id == fact_id
|
|
elif operation == "set_enabled":
|
|
result = await call_unwrapped(projects.patch_project_memory, "p1", projects.ProjectMemoryPatch(enabled=False), request)
|
|
assert result.enabled is False
|
|
elif operation == "delete":
|
|
result = await call_unwrapped(projects.delete_project_memory, "p1", fact_id, request)
|
|
assert result.facts == []
|
|
else:
|
|
result = await call_unwrapped(projects.promote_project_memory, "p1", fact_id, projects.ProjectMemoryPromotion(expected_instructions=""), request)
|
|
assert result.instructions == "- Reports exclude tax"
|
|
assert result.memory.facts == []
|
|
assert len(calls) == 1
|
|
assert calls[0][:2] == ("p1", "u1")
|