fixed memmory

This commit is contained in:
2026-06-10 08:32:20 +03:00
parent 5a9d26fbf4
commit c56471050c
6 changed files with 125 additions and 26 deletions
+39 -17
View File
@@ -2,13 +2,15 @@ import json
from datetime import datetime, timezone
from typing import Any
from sqlalchemy import func, or_, select
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.db.models import MemoryFact, SessionSummary, UserProfile
from app.memory.parse import normalize_text, parse_identity, texts_are_similar
DEFAULT_PROFILE: dict[str, Any] = {
"name": "",
"age": "",
"timezone": "",
"language": "ru",
"notes": "",
@@ -50,6 +52,20 @@ class MemoryService:
self.db.commit()
return {"ok": True, "profile": current}
def _find_similar_fact(self, text: str) -> MemoryFact | None:
for fact in self.db.scalars(
select(MemoryFact).where(MemoryFact.active.is_(True))
):
if texts_are_similar(fact.content, text):
return fact
return None
def _sync_identity_to_profile(self, text: str) -> dict[str, Any] | None:
parsed = parse_identity(text)
if not parsed:
return None
return self.update_profile(parsed)
def remember_fact(
self,
content: str,
@@ -63,26 +79,28 @@ class MemoryService:
if not text:
raise ValueError("Пустой факт")
existing = self.db.scalar(
select(MemoryFact).where(
MemoryFact.active.is_(True),
func.lower(MemoryFact.content) == text.lower(),
)
)
profile_sync = self._sync_identity_to_profile(text)
existing = self._find_similar_fact(text)
if existing:
if len(text) > len(existing.content):
existing.content = text[:2000]
existing.category = category or existing.category
existing.importance = max(existing.importance, min(5, max(1, importance)))
existing.updated_at = datetime.now(timezone.utc)
if session_id:
existing.session_id = session_id
self.db.commit()
return {
result = {
"ok": True,
"action": "updated",
"memory_id": existing.id,
"content": existing.content,
"category": existing.category,
}
if profile_sync:
result["profile"] = profile_sync.get("profile")
return result
fact = MemoryFact(
category=(category or "fact")[:64],
@@ -94,13 +112,16 @@ class MemoryService:
self.db.add(fact)
self.db.commit()
self.db.refresh(fact)
return {
result = {
"ok": True,
"action": "created",
"memory_id": fact.id,
"content": fact.content,
"category": fact.category,
}
if profile_sync:
result["profile"] = profile_sync.get("profile")
return result
def recall_memories(
self,
@@ -118,15 +139,16 @@ class MemoryService:
stmt = stmt.where(MemoryFact.active.is_(True))
if category:
stmt = stmt.where(MemoryFact.category == category)
facts = self.db.scalars(stmt.limit(100)).all()
if query:
pattern = f"%{query.strip()}%"
stmt = stmt.where(
or_(
MemoryFact.content.ilike(pattern),
MemoryFact.category.ilike(pattern),
)
)
facts = self.db.scalars(stmt.limit(min(limit, 50))).all()
qnorm = normalize_text(query)
facts = [
f
for f in facts
if qnorm in normalize_text(f.content)
or qnorm in normalize_text(f.category)
]
facts = facts[: min(limit, 50)]
return [
{
"id": f.id,