from __future__ import annotations from typing import ClassVar from .base import BaseAgent, AgentInput, AgentOutput _DOW_NAMES = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] class TimeOfDayAgent(BaseAgent): """Frames the current moment relative to the user's productive peak.""" agent_id: ClassVar[str] = "time-of-day" ttl_seconds: ClassVar[int] = 900 # 15m — must stay current-hour accurate version: ClassVar[str] = "1.0.0" def compute(self, inp: AgentInput) -> AgentOutput: hour = inp.now.hour dow = inp.now.weekday() # 0=Monday … 6=Sunday preferred = inp.profile.get("preferred_hour") is_weekend = dow >= 5 parts = [f"It is {hour:02d}:00 on {_DOW_NAMES[dow]} ({self._label(hour)})."] if is_weekend: parts.append("Weekend context — prefer personal or reflective tips over work tasks.") if preferred is not None: ph = int(preferred) delta = min(abs(hour - ph), 24 - abs(hour - ph)) # circular distance if delta == 0: parts.append( f"This is the user's peak productivity hour ({ph:02d}:00) — " f"a high-impact tip is appropriate." ) elif delta <= 2: parts.append(f"Approaching the user's peak productivity window ({ph:02d}:00).") else: parts.append("No preferred-hour data yet.") prompt = " ".join(parts) snapshot = {"hour": hour, "day_of_week": dow, "preferred_hour": preferred} return self._make_output(inp, prompt, snapshot) @staticmethod def _label(hour: int) -> str: if 5 <= hour < 12: return "morning" if 12 <= hour < 17: return "afternoon" if 17 <= hour < 21: return "evening" return "night"