from sqlalchemy.orm import Session as DBSession from app.db.models import Memory, Message, Session from app.core.config import MEMORY_SUMMARIZE_THRESHOLD from app.core import llm from app.core import knowledge from app.core.tagging import tag_memory def get_context_messages(db: DBSession, session_id: str) -> list[dict]: """蓄積知識・長期メモリ(要約)・短期メモリ(最近のメッセージ)を結合してコンテキストを返す。""" memories = db.query(Memory).filter(Memory.session_id == session_id).order_by(Memory.created_at).all() messages = db.query(Message).filter(Message.session_id == session_id).order_by(Message.created_at).all() context: list[dict] = [] knowledge_context = knowledge.get_knowledge_context(db) if knowledge_context: context.append({"role": "system", "content": knowledge_context}) if memories: combined_summary = "\n\n".join(m.summary for m in memories) context.append({ "role": "system", "content": f"以下はこの会話の過去の要約です:\n\n{combined_summary}", }) context.extend({"role": m.role, "content": m.content} for m in messages) return context async def maybe_summarize(db: DBSession, session: Session) -> None: """メッセージ数が閾値を超えたら古いメッセージを要約してMemoryに保存し、元メッセージを削除する。""" messages = db.query(Message).filter(Message.session_id == session.id).order_by(Message.created_at).all() if len(messages) < MEMORY_SUMMARIZE_THRESHOLD: return # 古いメッセージ(閾値の半分)を要約対象にする half = MEMORY_SUMMARIZE_THRESHOLD // 2 to_summarize = messages[:half] summary_prompt = [ {"role": "system", "content": "以下の会話を簡潔に要約してください。重要な事実・決定・文脈を保持してください。"}, *[{"role": m.role, "content": m.content} for m in to_summarize], ] summary_text = await llm.complete(summary_prompt, model=session.model, session_id=session.id) memory = Memory(session_id=session.id, summary=summary_text) db.add(memory) for msg in to_summarize: db.delete(msg) db.commit() db.refresh(memory) await tag_memory(db, memory)