Spaces:
Running
Running
| """Tests for the SQLite-backed three-tier long-term memory.""" | |
| from __future__ import annotations | |
| from memory import LongTermMemory | |
| def test_round_trip_semantic_facts() -> None: | |
| mem = LongTermMemory() | |
| fid = mem.remember_fact("user1", "dislike", "okra", source="user_stated") | |
| assert fid > 0 | |
| facts = mem.recall_facts("user1") | |
| assert len(facts) == 1 | |
| assert facts[0]["content"] == "okra" | |
| assert facts[0]["fact_type"] == "dislike" | |
| def test_filter_facts_by_type_and_substring() -> None: | |
| mem = LongTermMemory() | |
| mem.remember_fact("u1", "dislike", "okra") | |
| mem.remember_fact("u1", "dislike", "kale") | |
| mem.remember_fact("u1", "preference", "high-protein") | |
| mem.remember_fact("u2", "dislike", "okra") # different user | |
| dislikes = mem.recall_facts("u1", fact_type="dislike") | |
| assert {f["content"] for f in dislikes} == {"okra", "kale"} | |
| prefs = mem.recall_facts("u1", fact_type="preference") | |
| assert prefs[0]["content"] == "high-protein" | |
| okra_only = mem.recall_facts("u1", contains="okra") | |
| assert len(okra_only) == 1 | |
| def test_user_isolation() -> None: | |
| mem = LongTermMemory() | |
| mem.remember_fact("alice", "allergy", "peanut") | |
| mem.remember_fact("bob", "allergy", "shellfish") | |
| assert {f["content"] for f in mem.recall_facts("alice")} == {"peanut"} | |
| assert {f["content"] for f in mem.recall_facts("bob")} == {"shellfish"} | |
| def test_forget_fact() -> None: | |
| mem = LongTermMemory() | |
| fid = mem.remember_fact("u", "dislike", "okra") | |
| mem.forget_fact(fid) | |
| assert mem.recall_facts("u") == [] | |
| def test_procedural_records_round_trip() -> None: | |
| mem = LongTermMemory() | |
| issues = [{"code": "calorie_deviation", "description": "x", "severity": "medium"}] | |
| mem.remember_validation("u1", "1500 kcal plan", "revise", issues) | |
| history = mem.recall_validations("u1") | |
| assert len(history) == 1 | |
| assert history[0]["verdict"] == "revise" | |
| assert history[0]["issues"] == issues | |
| def test_episodic_session_round_trip() -> None: | |
| mem = LongTermMemory() | |
| payload = {"messages": [{"role": "user", "content": "hi"}], "memory": {"x": 1}} | |
| mem.remember_session("u1", "session-A", payload) | |
| sessions = mem.recall_sessions("u1") | |
| assert len(sessions) == 1 | |
| assert sessions[0]["payload"] == payload | |
| assert sessions[0]["session_id"] == "session-A" | |
| def test_recall_limit_and_order() -> None: | |
| mem = LongTermMemory() | |
| for i in range(15): | |
| mem.remember_fact("u", "note", f"fact-{i}") | |
| facts = mem.recall_facts("u", limit=5) | |
| assert len(facts) == 5 | |
| # newest first | |
| assert facts[0]["content"] == "fact-14" | |
| # NOTE: The KnowledgeAgent tests previously here have been removed. | |
| # KnowledgeAgent itself was removed; citation-first retrieval now happens | |
| # inside :class:`tools.WebSearchTool`, which returns citations natively | |
| # from Gemini's ``grounding_metadata``. Its coverage lives in the live | |
| # Gemini audit rather than the offline test suite. | |