"""Agent slots for due planned reviews.""" from __future__ import annotations from datetime import datetime, timezone from typing import Any from steering.eval_context import SteeringEvalContext def _parse_due(value: Any) -> datetime | None: if not value: return None if isinstance(value, datetime): return value if value.tzinfo else value.replace(tzinfo=timezone.utc) try: text = str(value).replace("Z", "+00:00") parsed = datetime.fromisoformat(text) return parsed if parsed.tzinfo else parsed.replace(tzinfo=timezone.utc) except ValueError: return None def resolve_review_due_slots(ctx: SteeringEvalContext) -> list[dict[str, Any]]: now = datetime.now(timezone.utc) slots: list[dict[str, Any]] = [] for review in ctx.reviews: if review.get("status") != "planned": continue due = _parse_due(review.get("due_at")) if due is None or due > now: continue slots.append( { "slot_key": "review.due", "scope_type": "review", "scope_id": str(review["id"]), "title": review.get("title") or "Review", "summary": "Geplantes Review ist fällig", "actor_role_hint": "reviewer", "payload_keys": ["review_id", "checklist_id"], "priority": "high" if due < now else "normal", "review_id": str(review["id"]), "action_id": ( str(review["action_id"]) if review.get("action_id") else None ), "milestone_id": ( str(review["milestone_id"]) if review.get("milestone_id") else None ), } ) return slots