feat: auto-trigger Discord wakeup when slot becomes ONGOING

This commit is contained in:
2026-04-05 09:37:14 +00:00
parent 57681c674f
commit 755c418391
3 changed files with 53 additions and 0 deletions

View File

@@ -53,6 +53,7 @@ from app.services.agent_status import (
transition_to_offline,
transition_to_exhausted,
)
from app.services.discord_wakeup import create_private_wakeup_channel
from app.services.minimum_workload import (
get_workload_config,
get_workload_warnings_for_date,
@@ -299,6 +300,45 @@ def _apply_agent_slot_update(slot: TimeSlot, payload: SlotAgentUpdate) -> None:
slot.attended = True
def _maybe_trigger_discord_wakeup(db: Session, slot: TimeSlot) -> dict | None:
"""Trigger Discord wakeup if slot became ONGOING and not already sent."""
# Only trigger for ONGOING status and if not already sent
if slot.status != SlotStatus.ONGOING or slot.wakeup_sent_at is not None:
return None
# Get user and check for discord_user_id
user = db.query(User).filter(User.id == slot.user_id).first()
if not user or not user.discord_user_id:
return None
# Get agent for this user
agent = db.query(Agent).filter(Agent.user_id == user.id).first()
agent_id_str = agent.agent_id if agent else "unknown"
# Build wakeup message
title = f"HarborForge Slot: {slot.event_type.value if slot.event_type else 'work'}"
message = (
f"🎯 **Slot started**\n"
f"Agent: `{agent_id_str}`\n"
f"Type: {slot.slot_type.value}\n"
f"Duration: {slot.estimated_duration}min\n"
f"Priority: {slot.priority}\n"
f"Use `hf calendar slot {slot.id}` for details."
)
try:
result = create_private_wakeup_channel(
discord_user_id=user.discord_user_id,
title=title,
message=message,
)
slot.wakeup_sent_at = datetime.now(timezone.utc)
return {"ok": True, "channel_id": result.get("channel_id")}
except Exception as e:
# Log but don't fail the slot update
return {"ok": False, "error": str(e)}
@router.api_route(
"/agent/heartbeat",
methods=["GET", "POST"],
@@ -338,6 +378,7 @@ def agent_update_real_slot(
if slot is None:
raise HTTPException(status_code=404, detail="Slot not found")
_apply_agent_slot_update(slot, payload)
_maybe_trigger_discord_wakeup(db, slot)
db.commit()
db.refresh(slot)
return TimeSlotEditResponse(slot=_slot_to_response(slot), warnings=[])
@@ -361,6 +402,7 @@ def agent_update_virtual_slot(
db.rollback()
raise HTTPException(status_code=404, detail="Slot not found")
_apply_agent_slot_update(slot, payload)
_maybe_trigger_discord_wakeup(db, slot)
db.commit()
db.refresh(slot)
return TimeSlotEditResponse(slot=_slot_to_response(slot), warnings=[])