feat: assemble memory context from facts and similar summaries
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V57jSQPqwkGG8BuAXg59X5
This commit is contained in:
parent
72d2bc379c
commit
33016bdf0a
|
|
@ -328,6 +328,28 @@ async def search_similar_conversation_summaries(query_embedding: list, exclude_c
|
|||
)
|
||||
|
||||
|
||||
async def build_memory_context(user_message: str, conversation_id: int) -> str:
|
||||
sections = []
|
||||
|
||||
facts = await get_all_memory_facts()
|
||||
if facts:
|
||||
facts_lines = "\n".join(f"- {f['content']}" for f in facts)
|
||||
sections.append(f"Bekannte Fakten ueber den Nutzer:\n{facts_lines}")
|
||||
|
||||
try:
|
||||
query_embedding = await get_embedding(user_message)
|
||||
summaries = await search_similar_conversation_summaries(query_embedding, conversation_id, limit=3)
|
||||
except Exception as e:
|
||||
logger.warning(f"Memory retrieval skipped, embedding/search failed: {e}")
|
||||
summaries = []
|
||||
|
||||
if summaries:
|
||||
summary_lines = "\n".join(f"- {s['summary']}" for s in summaries)
|
||||
sections.append(f"Relevante fruehere Gespraeche:\n{summary_lines}")
|
||||
|
||||
return "\n\n".join(sections)
|
||||
|
||||
|
||||
def _caldav_calendar():
|
||||
dav_root = NEXTCLOUD_CALDAV_URL.split("/calendars/")[0] + "/"
|
||||
client = caldav.DAVClient(url=dav_root, username=NEXTCLOUD_USER, password=NEXTCLOUD_APP_PASSWORD)
|
||||
|
|
|
|||
|
|
@ -141,3 +141,48 @@ async def test_execute_tool_dispatches_remember_and_forget_fact():
|
|||
with patch.object(main, "forget_fact", new=AsyncMock(return_value={"deleted": True, "content": "X"})):
|
||||
result = await main.execute_tool("forget_fact", {"query": "X"})
|
||||
assert json.loads(result) == {"deleted": True, "content": "X"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_build_memory_context_empty_when_nothing_stored():
|
||||
with patch.object(main, "get_all_memory_facts", new=AsyncMock(return_value=[])), patch.object(
|
||||
main, "get_embedding", new=AsyncMock(return_value=[0.1])
|
||||
), patch.object(main, "search_similar_conversation_summaries", new=AsyncMock(return_value=[])):
|
||||
context = await main.build_memory_context("Hallo", conversation_id=1)
|
||||
|
||||
assert context == ""
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_build_memory_context_includes_facts_section():
|
||||
facts = [{"id": 1, "content": "Hund heisst Bruno"}]
|
||||
with patch.object(main, "get_all_memory_facts", new=AsyncMock(return_value=facts)), patch.object(
|
||||
main, "get_embedding", new=AsyncMock(return_value=[0.1])
|
||||
), patch.object(main, "search_similar_conversation_summaries", new=AsyncMock(return_value=[])):
|
||||
context = await main.build_memory_context("Wie geht es meinem Hund?", conversation_id=1)
|
||||
|
||||
assert "Bekannte Fakten ueber den Nutzer" in context
|
||||
assert "Hund heisst Bruno" in context
|
||||
assert "Relevante fruehere Gespraeche" not in context
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_build_memory_context_includes_summaries_section():
|
||||
summaries = [{"conversation_id": 2, "summary": "Ging um den Kalender", "distance": 0.05}]
|
||||
with patch.object(main, "get_all_memory_facts", new=AsyncMock(return_value=[])), patch.object(
|
||||
main, "get_embedding", new=AsyncMock(return_value=[0.1])
|
||||
), patch.object(main, "search_similar_conversation_summaries", new=AsyncMock(return_value=summaries)):
|
||||
context = await main.build_memory_context("Was war nochmal mit dem Termin?", conversation_id=1)
|
||||
|
||||
assert "Relevante fruehere Gespraeche" in context
|
||||
assert "Ging um den Kalender" in context
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_build_memory_context_skips_summaries_when_embedding_fails():
|
||||
with patch.object(main, "get_all_memory_facts", new=AsyncMock(return_value=[])), patch.object(
|
||||
main, "get_embedding", new=AsyncMock(side_effect=RuntimeError("Ollama down"))
|
||||
):
|
||||
context = await main.build_memory_context("Hallo", conversation_id=1)
|
||||
|
||||
assert context == ""
|
||||
|
|
|
|||
Loading…
Reference in New Issue