From 58e7a76e1af2c17198bbb26540bd88e84e0defe2 Mon Sep 17 00:00:00 2001 From: hanghang zhang Date: Fri, 22 May 2026 22:34:10 +0100 Subject: [PATCH] =?UTF-8?q?feat(calendar):=20GET=20/agent/status=20?= =?UTF-8?q?=E2=80=94=20read-only=20status=20query=20for=20plugin=20gate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously only POST /agent/status existed (for state transitions). Fabric.OpenclawPlugin's triage on-call gate needs to check whether the on-duty agent is currently on_call without flipping their state — so the wake decision is read-only. GET returns {agent_id, status}, 404 if unknown. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) --- app/api/routers/calendar.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/app/api/routers/calendar.py b/app/api/routers/calendar.py index 1d00c98..d9b84f0 100644 --- a/app/api/routers/calendar.py +++ b/app/api/routers/calendar.py @@ -561,6 +561,29 @@ def agent_update_virtual_slot( return TimeSlotEditResponse(slot=_slot_to_response(slot), warnings=[]) +@router.get( + "/agent/status", + summary="Read an agent's current runtime status (no side effects)", +) +def get_agent_status( + agent_id: str = Query(..., description="Target agent_id"), + x_claw_identifier: str = Header(..., alias="X-Claw-Identifier"), + db: Session = Depends(get_db), +): + """Return `{agent_id, status}` so callers (Fabric.OpenclawPlugin's + triage on-call gate, etc.) can decide whether the agent is currently + eligible without flipping their state. + + No-op for unknown agents — returns 404 with `{detail: 'Agent not + found'}` so the caller can decide whether to fail-open or fail-closed. + """ + agent = _require_agent(db, agent_id, x_claw_identifier) + return { + "agent_id": agent.agent_id, + "status": agent.status.value if hasattr(agent.status, 'value') else str(agent.status), + } + + @router.post( "/agent/status", summary="Update agent runtime status from plugin",