from typing import Any from sqlalchemy.orm import Session from app.config import get_settings from app.memory.service import MemoryService from app.memory.parse import is_identity_question PROFILE_KEYS = ("name", "age", "timezone", "language", "notes") def get_memory_snapshot( db: Session, user_id: int, session_id: int | None = None, query: str | None = None, ) -> dict[str, Any]: return MemoryService(db, user_id).snapshot(session_id, query=query) def format_memory_context(snapshot: dict[str, Any]) -> str: lines = ["[Память и профиль — долгосрочный контекст]"] profile = snapshot.get("profile") or {} profile_lines = [] for key in PROFILE_KEYS: value = (profile.get(key) or "").strip() if value: profile_lines.append(f"- {key}: {value}") if profile_lines: lines.append("Профиль пользователя:") lines.extend(profile_lines) else: lines.append("Профиль: не заполнен (можно уточнить имя, часовой пояс).") summary = (snapshot.get("session_summary") or "").strip() if summary: lines.append("") lines.append("Сводка текущего чата (ранние сообщения):") lines.append(summary) facts = snapshot.get("facts") or [] if facts: lines.append("") lines.append(f"Запомненные факты ({snapshot.get('total_facts', len(facts))}):") limit = get_settings().memory_facts_in_context for fact in facts[:limit]: lines.append( f"- [{fact.get('category')}] #{fact.get('id')} {fact.get('content')}" ) else: lines.append("") lines.append("Запомненные факты: пока нет.") lines.append("") lines.append( "Правила памяти: " "«запомни» → remember_fact (имя/возраст также пишутся в профиль). " "«кто я» / «сколько мне лет» → ответь из профиля и фактов выше, БЕЗ выдумок. " "Роль персонажа (сын, мать и т.п.) — стиль общения, НЕ биография пользователя. " "Если профиль и факты пусты — честно скажи «не помню» и предложи запомнить. " "«забудь #N» → forget_memory. " "Длинный чат — update_session_summary." ) return "\n".join(lines) def format_identity_hint(snapshot: dict[str, Any], user_text: str) -> str: if not is_identity_question(user_text): return "" profile = snapshot.get("profile") or {} facts = snapshot.get("facts") or [] lines = [ "[Вопрос об идентичности пользователя]", "Ответь ТОЛЬКО из данных ниже. Не придумывай роли из сценария персонажа.", ] name = (profile.get("name") or "").strip() age = (profile.get("age") or "").strip() if name: lines.append(f"Имя: {name}") if age: lines.append(f"Возраст: {age} лет") for fact in facts: lines.append(f"Факт: {fact.get('content')}") if not name and not age and not facts: lines.append("Данных нет — скажи, что не помнишь.") return "\n".join(lines)