fix(config,vibegram): triage wakes master by alias with wake urgency, event times in local tz

This commit is contained in:
hh
2026-08-30 20:34:17 +02:00
parent 05fcfb6447
commit ec55994fc7
2 changed files with 25 additions and 12 deletions
+6 -3
View File
@@ -204,6 +204,7 @@ VIBEGRAM = (
token=os.environ["VIBEGRAM_TOKEN"], token=os.environ["VIBEGRAM_TOKEN"],
nick=os.environ.get("VIBEGRAM_NICK", "beaver-test"), nick=os.environ.get("VIBEGRAM_NICK", "beaver-test"),
repo=VIBEGRAM_REPO if VIBEGRAM_REPO.exists() else None, repo=VIBEGRAM_REPO if VIBEGRAM_REPO.exists() else None,
tz=TZ,
) )
if os.environ.get("VIBEGRAM_TOKEN") if os.environ.get("VIBEGRAM_TOKEN")
else None else None
@@ -560,9 +561,11 @@ _vibegram_backlog: list[str] = []
VIBEGRAM_BRIEF = ( VIBEGRAM_BRIEF = (
"Новое в вайбграме (комната {room}, ты там {nick}; остальные - чужие агенты):\n" "Новое в вайбграме (комната {room}, ты там {nick}; остальные - чужие агенты):\n"
"{items}\n" "{items}\n"
"Будить мастера - inject(master, резюме до 3 строк: кто, что, чего ждёт). " 'Будить мастера - inject(conversation="master", urgency="wake", '
"Мастер прочитает подробности через vibegram(read) и ответит через " "text=резюме до 3 строк: кто, что, чего ждёт). Мастер прочитает подробности "
"vibegram(send), если решит." "через vibegram(read) и ответит через vibegram(send), если решит. "
"Если inject вернул ошибку - это сбой доставки, а не «не срочно»: повтори "
"один раз с тем же текстом; без inject резюме никто не увидит."
) )
+19 -9
View File
@@ -20,6 +20,7 @@ from dataclasses import dataclass, field
from datetime import UTC, datetime from datetime import UTC, datetime
from pathlib import Path # noqa: TC003 - в аннотации dataclass from pathlib import Path # noqa: TC003 - в аннотации dataclass
from typing import Any, Literal from typing import Any, Literal
from zoneinfo import ZoneInfo
import aiohttp import aiohttp
@@ -49,6 +50,8 @@ class Vibegram:
token: str token: str
nick: str nick: str
repo: Path | None = None repo: Path | None = None
tz: str = "UTC"
"""Время в строках событий - в этой зоне (хаб отдаёт UTC)."""
timeout: float = 15.0 timeout: float = 15.0
max_chars: int = 8_000 max_chars: int = 8_000
_cursor: int = 0 _cursor: int = 0
@@ -126,7 +129,11 @@ class Vibegram:
async def pending(self, limit: int = 50) -> list[Event]: async def pending(self, limit: int = 50) -> list[Event]:
"""Новые события с курсора хаба (для крона); запоминает их.""" """Новые события с курсора хаба (для крона); запоминает их."""
data = await self._get(f"/api/pending?limit={limit}") data = await self._get(f"/api/pending?limit={limit}")
events = [e for e in map(_event, data.get("events", [])) if e is not None] events = [
e
for e in (_event(raw, self.tz) for raw in data.get("events", []))
if e is not None
]
fresh = [e for e in events if e.id > self._cursor] fresh = [e for e in events if e.id > self._cursor]
for e in fresh: for e in fresh:
self._recent.append(e) self._recent.append(e)
@@ -139,7 +146,7 @@ class Vibegram:
nick="system", nick="system",
kind="plan", kind="plan",
text=f"план изменился (ревизия {ack}), ты его не подтвердил", text=f"план изменился (ревизия {ack}), ты его не подтвердил",
at=_now(), at=_now(self.tz),
) )
) )
return fresh return fresh
@@ -210,18 +217,21 @@ class HubError(RuntimeError):
self.code = code self.code = code
def _now() -> str: def _now(tz: str = "UTC") -> str:
return datetime.now(UTC).strftime("%m-%d %H:%M") return datetime.now(UTC).astimezone(ZoneInfo(tz)).strftime("%m-%d %H:%M")
def _when(iso: Any) -> str: def _when(iso: Any, tz: str = "UTC") -> str:
try: try:
return datetime.fromisoformat(str(iso)).strftime("%m-%d %H:%M") when = datetime.fromisoformat(str(iso))
except ValueError: except ValueError:
return _now() return _now(tz)
if when.tzinfo is None:
when = when.replace(tzinfo=UTC)
return when.astimezone(ZoneInfo(tz)).strftime("%m-%d %H:%M")
def _event(raw: dict[str, Any]) -> Event | None: def _event(raw: dict[str, Any], tz: str = "UTC") -> Event | None:
who = raw.get("nick") or "system" who = raw.get("nick") or "system"
kind = str(raw.get("kind") or "") kind = str(raw.get("kind") or "")
p = raw.get("payload") or {} p = raw.get("payload") or {}
@@ -249,7 +259,7 @@ def _event(raw: dict[str, Any]) -> Event | None:
nick=str(who), nick=str(who),
kind=kind, kind=kind,
text=text, text=text,
at=_when(raw.get("createdAt")), at=_when(raw.get("createdAt"), tz),
) )