feat: add /calendar/sync endpoint for multi-agent schedule sync
Returns today's slots for all agents on a claw instance, keyed by agent_id. Used by HF Plugin to maintain a local schedule cache instead of per-agent heartbeat. Also records heartbeat for all agents on the instance. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -361,6 +361,62 @@ def agent_heartbeat(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get(
|
||||||
|
"/sync",
|
||||||
|
summary="Sync today's schedules for all agents on a claw instance",
|
||||||
|
)
|
||||||
|
def sync_schedules(
|
||||||
|
x_claw_identifier: str = Header(..., alias="X-Claw-Identifier"),
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
):
|
||||||
|
"""Return today's slots for all agents belonging to the given claw instance.
|
||||||
|
|
||||||
|
Used by the HF OpenClaw plugin to maintain a local schedule cache.
|
||||||
|
Returns a dict of { agent_id: [slots] } for all agents with matching
|
||||||
|
claw_identifier.
|
||||||
|
"""
|
||||||
|
today = date_type.today()
|
||||||
|
|
||||||
|
# Find all agents on this claw instance
|
||||||
|
agents = (
|
||||||
|
db.query(Agent)
|
||||||
|
.filter(Agent.claw_identifier == x_claw_identifier)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
|
schedules: dict[str, list[dict]] = {}
|
||||||
|
for agent in agents:
|
||||||
|
# Get real slots for today
|
||||||
|
real_slots = (
|
||||||
|
db.query(TimeSlot)
|
||||||
|
.filter(
|
||||||
|
TimeSlot.user_id == agent.user_id,
|
||||||
|
TimeSlot.date == today,
|
||||||
|
TimeSlot.status.notin_(list(_INACTIVE_STATUSES)),
|
||||||
|
)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
items = [_real_slot_to_item(s).model_dump(mode="json") for s in real_slots]
|
||||||
|
|
||||||
|
# Get virtual plan slots
|
||||||
|
virtual_slots = get_virtual_slots_for_date(db, agent.user_id, today)
|
||||||
|
for vs in virtual_slots:
|
||||||
|
items.append(_virtual_slot_to_item(vs).model_dump(mode="json"))
|
||||||
|
|
||||||
|
schedules[agent.agent_id] = items
|
||||||
|
|
||||||
|
# Record heartbeat for liveness
|
||||||
|
for agent in agents:
|
||||||
|
record_heartbeat(db, agent)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
return {
|
||||||
|
"schedules": schedules,
|
||||||
|
"date": today.isoformat(),
|
||||||
|
"agent_count": len(agents),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@router.patch(
|
@router.patch(
|
||||||
"/slots/{slot_id}/agent-update",
|
"/slots/{slot_id}/agent-update",
|
||||||
response_model=TimeSlotEditResponse,
|
response_model=TimeSlotEditResponse,
|
||||||
|
|||||||
Reference in New Issue
Block a user