from fastapi.testclient import TestClient from duck_core.api import create_app from duck_core.memory.store import MemoryStore def test_memory_api_stores_workspace_scoped_notes(tmp_path, monkeypatch): monkeypatch.setenv("DUCK_DB_PATH", str(tmp_path / "duck.sqlite3")) client = TestClient(create_app()) first = client.post( "/v1/memory", json={ "text": "User prefers concise Russian answers.", "workspace": "/tmp/project-a", "conversation_id": "chat_a", "memory_type": "preference", "importance": 0.8, }, ).json() client.post( "/v1/memory", json={ "text": "Different workspace note.", "workspace": "/tmp/project-b", "conversation_id": "chat_b", }, ) listed = client.get("/v1/memory", params={"workspace": "/tmp/project-a"}).json() search = client.get( "/v1/memory/search", params={"q": "concise Russian", "workspace": "/tmp/project-a"}, ).json() assert first["memory_id"].startswith("mem_") assert [item["text"] for item in listed["results"]] == [ "User prefers concise Russian answers." ] assert search["results"][0]["memory_id"] == first["memory_id"] assert search["results"][0]["memory_type"] == "preference" assert "Different workspace note." not in str(search) async def test_memory_store_searches_text_and_metadata(tmp_path): store = MemoryStore(str(tmp_path / "duck.sqlite3")) await store.init() await store.add( text="RX580 should use Vulkan builds.", workspace="/tmp/duck", conversation_id="chat_runtime", memory_type="fact", importance=0.9, metadata={"topic": "gpu"}, ) results = await store.search("vulkan", workspace="/tmp/duck") assert len(results) == 1 assert results[0].workspace == "/tmp/duck" assert results[0].metadata["topic"] == "gpu"