81 lines
2.7 KiB
Bash
81 lines
2.7 KiB
Bash
#!/bin/bash
|
|
# Periodic worker health check: orphan bead recovery and idle worker nudging.
|
|
# Usage: anvillm-worker-check [--orphans] [--nudge]
|
|
set -euo pipefail
|
|
|
|
LOG_PREFIX="[worker-check $(date '+%Y-%m-%d %H:%M:%S')]"
|
|
log() { echo "$LOG_PREFIX $*"; }
|
|
|
|
DO_ORPHANS=0
|
|
DO_NUDGE=0
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--orphans) DO_ORPHANS=1; shift ;;
|
|
--nudge) DO_NUDGE=1; shift ;;
|
|
*) echo "unknown argument: $1" >&2; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
if [ "$DO_ORPHANS" -eq 0 ] && [ "$DO_NUDGE" -eq 0 ]; then
|
|
echo "usage: anvillm-worker-check [--orphans] [--nudge]" >&2
|
|
exit 1
|
|
fi
|
|
|
|
SESSIONS=$(9p read anvillm/list 2>/dev/null || true)
|
|
|
|
# --- Orphan recovery ---
|
|
if [ "$DO_ORPHANS" -eq 1 ]; then
|
|
LIVE_SESSIONS=$(echo "$SESSIONS" | awk -F'\t' '{print $1}' || true)
|
|
|
|
MTAB=$(9p read anvillm/beads/mtab 2>/dev/null || true)
|
|
if [ -z "$MTAB" ]; then
|
|
log "orphans: no mounts, nothing to do"
|
|
else
|
|
while IFS=$'\t' read -r MOUNT CWD; do
|
|
[ -z "$MOUNT" ] && continue
|
|
|
|
IN_PROGRESS=$(9p read "anvillm/beads/$MOUNT/list" 2>/dev/null \
|
|
| jq -r '.[] | select(.status == "in_progress") | [.id, (.assignee // "")] | @tsv' \
|
|
2>/dev/null || true)
|
|
|
|
[ -z "$IN_PROGRESS" ] && continue
|
|
|
|
while IFS=$'\t' read -r BEAD_ID ASSIGNEE; do
|
|
[ -z "$BEAD_ID" ] && continue
|
|
[ "$ASSIGNEE" = "user" ] && continue
|
|
if [ -n "$ASSIGNEE" ] && echo "$LIVE_SESSIONS" | grep -qx "$ASSIGNEE"; then
|
|
continue
|
|
fi
|
|
log "orphan: $BEAD_ID (was: ${ASSIGNEE:-unassigned}) mount=$MOUNT — unclaiming"
|
|
echo "unclaim $BEAD_ID" | 9p write "anvillm/beads/$MOUNT/ctl" 2>/dev/null || \
|
|
log "WARNING: unclaim failed for $BEAD_ID"
|
|
done <<< "$IN_PROGRESS"
|
|
done <<< "$MTAB"
|
|
fi
|
|
fi
|
|
|
|
# --- Nudge idle workers ---
|
|
if [ "$DO_NUDGE" -eq 1 ]; then
|
|
[ -z "$SESSIONS" ] && { log "nudge: no sessions"; exit 0; }
|
|
|
|
BODY='Use the execute_code tool to run wait_for_bead.sh and check for available work.'
|
|
|
|
while IFS=$'\t' read -r ID BACKEND STATE ALIAS ROLE CWD; do
|
|
[ -z "$ID" ] && continue
|
|
[ "$STATE" != "idle" ] && continue
|
|
[ "$ROLE" = "-" ] || [ -z "$ROLE" ] && continue
|
|
|
|
ROLE_CONTENT=$(9p read "anvillm/roles/${ROLE}.md" 2>/dev/null || true)
|
|
echo "$ROLE_CONTENT" | grep -q '^worker: true' || continue
|
|
|
|
log "nudge: $ID (role=$ROLE)"
|
|
AGENT_ID=user send_message.sh \
|
|
--to "$ID" \
|
|
--type prompt_request \
|
|
--subject work \
|
|
--body "$BODY" || \
|
|
log "WARNING: nudge failed for $ID"
|
|
done <<< "$SESSIONS"
|
|
fi
|