from __future__ import annotations import time from typing import Any class MessageHistory: MAX_MESSAGES = 500 TTL_SECONDS = 3600 def __init__(self) -> None: self._history: dict[str, list[dict[str, Any]]] = {} def add(self, chat_guid: str, message: dict[str, Any]) -> None: if chat_guid not in self._history: self._history[chat_guid] = [] self._history[chat_guid].append( { **message, "_recorded_at": time.monotonic(), } ) self._trim(chat_guid) def get(self, chat_guid: str, limit: int = 50) -> list[dict[str, Any]]: messages = self._history.get(chat_guid, []) self._evict_expired(chat_guid) return messages[-limit:] def get_since(self, chat_guid: str, since_ts: float) -> list[dict[str, Any]]: messages = self._history.get(chat_guid, []) self._evict_expired(chat_guid) return [m for m in messages if m.get("_recorded_at", 0) >= since_ts] def _trim(self, chat_guid: str) -> None: messages = self._history.get(chat_guid, []) if len(messages) > self.MAX_MESSAGES: self._history[chat_guid] = messages[-self.MAX_MESSAGES :] def _evict_expired(self, chat_guid: str) -> None: messages = self._history.get(chat_guid, []) if not messages: return now = time.monotonic() self._history[chat_guid] = [m for m in messages if now - m.get("_recorded_at", now) < self.TTL_SECONDS] def clear(self, chat_guid: str) -> None: self._history.pop(chat_guid, None)