Manage Heartbeats
Auth note: Use
from dashboard.backend.sdk_client import evo— auto-handles URL + auth, no Bearer token needed in code.
Inspect and control existing heartbeats — list them, enable/disable, trigger manual runs, review run history.
When to use
Use this skill when the user wants to:
- See which heartbeats exist and their status
- Enable a heartbeat they set up but left disabled
- Disable a heartbeat that's costing too much or misbehaving
- Manually trigger a run (outside the normal interval)
- Review recent runs and decide if the heartbeat is working
Don't use this to create new heartbeats — use /create-heartbeat.
Step 1: List all heartbeats
from dashboard.backend.sdk_client import evo
heartbeats = evo.get("/api/heartbeats")
Response shape per heartbeat: id, agent, interval_seconds, enabled, last_run_at, last_run_status, last_run_cost_usd, next_trigger_at.
Present to user as a table:
- ID
- Agent
- Status (enabled / disabled)
- Interval (human format: "every 4h")
- Last run (time + status)
- Cost 7d (sum of
cost_usdin last 7 days)
Step 2: Detailed view (one heartbeat)
from dashboard.backend.sdk_client import evo
hb = evo.get(f"/api/heartbeats/{hb_id}")
Includes last 10 runs with full fields: started_at, ended_at, duration_ms, tokens_in, tokens_out, cost_usd, status, prompt_preview, error.
Show the user the latest 3 runs, summarize patterns (always-skip / always-act / mixed).
Step 3: Enable / disable
from dashboard.backend.sdk_client import evo
# Enable
evo.patch(f"/api/heartbeats/{hb_id}", {"enabled": True})
# Disable (preserves data, just stops the dispatcher from scheduling)
evo.patch(f"/api/heartbeats/{hb_id}", {"enabled": False})
Warn the user:
- Enable doesn't run immediately — next trigger fires at the top of the next interval.
- Disable doesn't cancel a currently-running execution.
Step 4: Run Now (manual trigger)
from dashboard.backend.sdk_client import evo
result = evo.post(f"/api/heartbeats/{hb_id}/run")
Response {"run_id": "...", "status": "queued"} within ~500ms. Execution happens async.
Tell the user:
- Run logs appear in
workspace/ADWs/logs/heartbeats/<id>-<date>.jsonlin real time. - Or poll
GET /api/heartbeats/<id>to seelast_run_statusflip fromrunning→success/fail/timeout.
Step 5: Paginated run history
from dashboard.backend.sdk_client import evo
runs = evo.get(f"/api/heartbeats/{hb_id}/runs", params={"limit": 50})
Useful to audit a heartbeat that was misbehaving historically. Filter by:
?status=fail— only failures?status=timeout— only timeouts?from=YYYY-MM-DD&to=YYYY-MM-DD— date range
Step 6: Delete (rare)
Only if truly obsolete:
from dashboard.backend.sdk_client import evo
# Gracefully — returns 409 if currently running
evo.delete(f"/api/heartbeats/{hb_id}")
# Force-kill currently-running
evo.delete(f"/api/heartbeats/{hb_id}", params={"force": "true"})
Confirm with user before forcing. Disable first, then delete once runs stop.
Notes
- UI equivalent:
/scheduler→ Heartbeats tab. The skill is useful for scripted management or when Davidson prefers CLI. - Cost visibility:
/costsshows heartbeat cost per agent alongside routine costs.
Related: .claude/rules/heartbeats.md, /create-heartbeat.