fix(config,vibegram): triage wakes master by alias with wake urgency, event times in local tz
This commit is contained in:
@@ -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
@@ -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),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user