90 lines
3.6 KiB
Python
90 lines
3.6 KiB
Python
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)
|