142 lines
4.5 KiB
Bash
Executable File
142 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Watchdog B v2 dispatcher/runner.
|
|
# Unified entrypoint for timer/service/manual runs.
|
|
#
|
|
# Flow:
|
|
# 1) Call check_openclaw_state.sh to get one of: running | stalled | idle
|
|
# 2) Emit a human-readable action template for the detected state
|
|
# 3) Invoke the notification layer (dry-run/manual by default, configurable)
|
|
# 4) Persist rendered output for local verification / future integrations
|
|
#
|
|
# Notification behavior is intentionally conservative:
|
|
# - running: defaults to a manual/queue-ready owner report path
|
|
# - stalled/idle: nudge main agent first, then optionally escalate to owner report
|
|
# - outbound owner messaging reuses the existing owner-reporting-system queue
|
|
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
SKILL_DIR="$(cd -- "$SCRIPT_DIR/.." && pwd)"
|
|
WATCHDOG_B_CONFIG_FILE_DEFAULT="$HOME/.config/openclaw/watchdog-b.env"
|
|
WATCHDOG_B_CONFIG_FILE="${WATCHDOG_B_CONFIG_FILE:-$WATCHDOG_B_CONFIG_FILE_DEFAULT}"
|
|
if [[ -f "$WATCHDOG_B_CONFIG_FILE" ]]; then
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
. "$WATCHDOG_B_CONFIG_FILE"
|
|
set +a
|
|
fi
|
|
|
|
WORKSPACE_DEFAULT="$HOME/.openclaw/workspace"
|
|
WORKSPACE_DIR="${WATCHDOG_B_WORKSPACE:-$WORKSPACE_DEFAULT}"
|
|
CHECKER="${WATCHDOG_B_CHECKER:-$SCRIPT_DIR/check_openclaw_state.sh}"
|
|
ARTIFACT_DIR="${WATCHDOG_B_ARTIFACT_DIR:-$WORKSPACE_DIR/state/watchdog-b}"
|
|
TIMESTAMP="$(date '+%Y-%m-%dT%H:%M:%S%z')"
|
|
HOSTNAME_VALUE="$(hostname 2>/dev/null || echo unknown-host)"
|
|
NOTIFIER="${WATCHDOG_B_NOTIFIER:-$SCRIPT_DIR/notify_watchdog_b.py}"
|
|
NOTIFY_DRY_RUN="${WATCHDOG_B_NOTIFY_DRY_RUN:-1}"
|
|
|
|
mkdir -p "$ARTIFACT_DIR"
|
|
|
|
if [[ ! -x "$CHECKER" ]]; then
|
|
echo "watchdog-b error: checker not executable: $CHECKER" >&2
|
|
exit 1
|
|
fi
|
|
|
|
STATE="$($CHECKER)"
|
|
|
|
emit_running() {
|
|
cat <<EOF
|
|
WATCHDOG_B_STATE=running
|
|
WATCHDOG_B_TIMESTAMP=$TIMESTAMP
|
|
WATCHDOG_B_HOST=$HOSTNAME_VALUE
|
|
WATCHDOG_B_ACTION=progress-template
|
|
WATCHDOG_B_TEMPLATE_BEGIN
|
|
[watchdog-b][running] OpenClaw main runtime appears active.
|
|
Suggested future progress-report message template:
|
|
- Status: still running
|
|
- Checked at: $TIMESTAMP
|
|
- Host: $HOSTNAME_VALUE
|
|
- Summary: main runtime is alive and log activity is fresh.
|
|
- Next step: if desired, attach latest task/progress snapshot before sending.
|
|
WATCHDOG_B_TEMPLATE_END
|
|
WATCHDOG_B_NEXT_HOOK=progress_report_stub
|
|
EOF
|
|
}
|
|
|
|
emit_stalled() {
|
|
cat <<EOF
|
|
WATCHDOG_B_STATE=stalled
|
|
WATCHDOG_B_TIMESTAMP=$TIMESTAMP
|
|
WATCHDOG_B_HOST=$HOSTNAME_VALUE
|
|
WATCHDOG_B_ACTION=nudge-template
|
|
WATCHDOG_B_TEMPLATE_BEGIN
|
|
[watchdog-b][stalled] OpenClaw main runtime looks alive but may be stuck.
|
|
Suggested future nudge/escalation template:
|
|
- Audience: main agent and/or Eric
|
|
- Checked at: $TIMESTAMP
|
|
- Host: $HOSTNAME_VALUE
|
|
- Observation: process is alive, but activity log appears stale beyond threshold.
|
|
- Suggested ask: please confirm current task state, unblock reason, or whether intervention is needed.
|
|
WATCHDOG_B_TEMPLATE_END
|
|
WATCHDOG_B_NEXT_HOOK=stalled_nudge_stub
|
|
EOF
|
|
}
|
|
|
|
emit_idle() {
|
|
cat <<EOF
|
|
WATCHDOG_B_STATE=idle
|
|
WATCHDOG_B_TIMESTAMP=$TIMESTAMP
|
|
WATCHDOG_B_HOST=$HOSTNAME_VALUE
|
|
WATCHDOG_B_ACTION=idle-template
|
|
WATCHDOG_B_TEMPLATE_BEGIN
|
|
[watchdog-b][idle] OpenClaw main runtime does not appear to be actively running.
|
|
Suggested future reminder template:
|
|
- Audience: main agent and/or Eric
|
|
- Checked at: $TIMESTAMP
|
|
- Host: $HOSTNAME_VALUE
|
|
- Observation: no live runtime detected from pid/log heuristic.
|
|
- Suggested ask: confirm whether the runtime should be started, ignored, or left idle.
|
|
WATCHDOG_B_TEMPLATE_END
|
|
WATCHDOG_B_NEXT_HOOK=idle_reminder_stub
|
|
EOF
|
|
}
|
|
|
|
case "$STATE" in
|
|
running)
|
|
OUTPUT="$(emit_running)"
|
|
;;
|
|
stalled)
|
|
OUTPUT="$(emit_stalled)"
|
|
;;
|
|
idle)
|
|
OUTPUT="$(emit_idle)"
|
|
;;
|
|
*)
|
|
echo "watchdog-b error: unexpected state from checker: $STATE" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
|
|
printf '%s\n' "$OUTPUT"
|
|
|
|
NOTIFY_OUTPUT=""
|
|
if [[ -x "$NOTIFIER" ]]; then
|
|
NOTIFY_CMD=("$NOTIFIER" --state "$STATE" --timestamp "$TIMESTAMP")
|
|
if [[ "$NOTIFY_DRY_RUN" == "1" ]]; then
|
|
NOTIFY_CMD+=(--dry-run)
|
|
fi
|
|
if NOTIFY_OUTPUT="$(WATCHDOG_B_ARTIFACT_DIR="$ARTIFACT_DIR" "${NOTIFY_CMD[@]}" 2>&1)"; then
|
|
printf '%s\n' "$NOTIFY_OUTPUT"
|
|
else
|
|
printf '%s\n' "$NOTIFY_OUTPUT"
|
|
echo "watchdog-b warning: notifier returned non-zero for state=$STATE" >&2
|
|
fi
|
|
else
|
|
echo "watchdog-b warning: notifier not executable: $NOTIFIER" >&2
|
|
fi
|
|
|
|
printf '%s\n' "$OUTPUT" > "$ARTIFACT_DIR/last-output.txt"
|
|
printf '%s\n' "$NOTIFY_OUTPUT" > "$ARTIFACT_DIR/last-notify-output.txt"
|
|
printf '%s\t%s\n' "$TIMESTAMP" "$STATE" >> "$ARTIFACT_DIR/history.tsv"
|
|
printf '%s\n' "$STATE" > "$ARTIFACT_DIR/last-state.txt"
|