"""Память: воскресная перезапись состояния из хендаутов и куратор по расписанию.""" from __future__ import annotations import logging from typing import TYPE_CHECKING from beaver_gateway.conversations.distill import LineCap from beaver_agent.memory.curator import briefing from beaver_agent.memory.watch import CURATOR_WATCH from beaver_agent.vault import ( CURATOR_JOURNAL, DAYS, REPLIES, STATE, STATE_MAX_LINES, TZ, VAULT, today, ) if TYPE_CHECKING: from beaver_gateway.jobs.scheduler import JobRun _log = logging.getLogger(__name__) REWRITE_STATE = ( "Воскресенье, {day}. Перепиши `{state}` из последних хендаутов: {handouts}. " "`## сейчас` - только невыводимое из vault, `## мои хвосты` - capability " "requests в работе и обещания длиннее дня. Меньше {max_lines} строк." ) async def memory(run: JobRun) -> None: """Потолок строк держит gateway: слишком длинный файл откатывается.""" handouts = sorted(DAYS.glob("????-??-??.md"))[-7:] if DAYS.exists() else [] if not handouts: _log.info("memory: no handouts yet, nothing to rewrite") return await run.spawn_job( agent="beaver-distiller", title="память", text=REWRITE_STATE.format( day=today(), state=STATE.relative_to(VAULT), handouts=", ".join(f"`{h.relative_to(VAULT)}`" for h in handouts), max_lines=STATE_MAX_LINES, ), line_cap=LineCap(STATE, max_lines=STATE_MAX_LINES), ) async def curate(run: JobRun) -> None: """Крон собирает «что нового», модель раскладывает; пусто - джоб не спавнится.""" text = briefing( vault=VAULT, journal=CURATOR_JOURNAL, replies_dir=REPLIES, watched=CURATOR_WATCH, tz=TZ, ) if text is None: _log.info("curator: nothing new since the last run") return await run.spawn_job(agent="beaver-curator", title="куратор", text=text)