OpenClaw-Setup/openclaw-setup-copilot/scripts/copilot_auth_watchdog.sh

135 lines
3.7 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
CONFIG_PATH="${AUTH_WATCHDOG_CONFIG:-$ROOT_DIR/config/copilot-auth-watchdog.config.json}"
if ! command -v jq >/dev/null 2>&1; then
echo "[copilot-auth-watchdog] jq is required" >&2
exit 1
fi
expand_tilde() {
local p="$1"
if [[ "$p" == "~" ]]; then
echo "$HOME"
elif [[ "$p" == "~/"* ]]; then
echo "$HOME/${p#~/}"
else
echo "$p"
fi
}
now_ms() {
python3 - <<'PY'
import time
print(int(time.time()*1000))
PY
}
send_notice() {
local text="$1"
local last_channel="$2"
local last_to="$3"
if [[ -z "$last_channel" || -z "$last_to" ]]; then
echo "[copilot-auth-watchdog] notice skipped (missing channel/target): $text" >&2
return 0
fi
local target="$last_to"
if [[ "$target" == *:* ]]; then
target="${target#*:}"
fi
openclaw message send \
--channel "$last_channel" \
--target "$target" \
--message "$text" \
>/dev/null 2>&1 || true
}
if [[ ! -f "$CONFIG_PATH" ]]; then
echo "[copilot-auth-watchdog] missing config: $CONFIG_PATH" >&2
exit 1
fi
enabled="$(jq -r '.enabled // true' "$CONFIG_PATH")"
if [[ "$enabled" != "true" ]]; then
exit 0
fi
session_key="$(jq -r '.sessionKey // "agent:main:main"' "$CONFIG_PATH")"
alert_interval_min="$(jq -r '.minAlertIntervalMinutes // 30' "$CONFIG_PATH")"
state_file_raw="$(jq -r '.stateFile // "~/.openclaw/copilot-auth-watchdog-state.json"' "$CONFIG_PATH")"
state_file="$(expand_tilde "$state_file_raw")"
check_model_status="$(jq -r '.checkOpenClawModelStatus // true' "$CONFIG_PATH")"
state_dir="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
sessions_file="$state_dir/agents/main/sessions/sessions.json"
last_channel=""
last_to=""
if [[ -r "$sessions_file" ]]; then
session_json="$(jq -c --arg key "$session_key" '.[$key] // {}' "$sessions_file" 2>/dev/null || true)"
if [[ -n "$session_json" && "$session_json" != "{}" ]]; then
last_channel="$(jq -r '.lastChannel // empty' <<<"$session_json")"
last_to="$(jq -r '.lastTo // empty' <<<"$session_json")"
fi
fi
declare -a issues=()
if ! command -v copilot >/dev/null 2>&1; then
issues+=("copilot CLI not installed; run setup_openclaw_copilot.sh")
else
set +e
copilot_out="$(copilot auth status 2>&1)"
copilot_rc=$?
set -e
if [[ $copilot_rc -ne 0 ]]; then
issues+=("copilot auth status failed; run: copilot auth login")
elif echo "$copilot_out" | grep -Eiq 'not authenticated|not logged|login required|expired|unauthorized|invalid'; then
issues+=("copilot auth not healthy; run: copilot auth login")
fi
fi
if [[ "$check_model_status" == "true" ]]; then
if ! command -v openclaw >/dev/null 2>&1; then
issues+=("openclaw CLI not installed")
else
if ! openclaw models status --check >/dev/null 2>&1; then
issues+=("openclaw model auth check failed; run: openclaw models status --json and copilot auth login")
fi
fi
fi
if [[ ${#issues[@]} -eq 0 ]]; then
exit 0
fi
mkdir -p "$(dirname "$state_file")"
if [[ ! -f "$state_file" ]]; then
printf '{}\n' > "$state_file"
fi
state_json="$(cat "$state_file")"
last_alert_at="$(jq -r --arg key "$session_key" '.[$key].lastAlertAt // 0' <<<"$state_json")"
if [[ ! "$last_alert_at" =~ ^[0-9]+$ ]]; then
last_alert_at=0
fi
now="$(now_ms)"
interval_ms=$((alert_interval_min * 60 * 1000))
if (( now - last_alert_at < interval_ms )); then
exit 0
fi
summary="Copilot auth watchdog alert: ${issues[*]}"
echo "[copilot-auth-watchdog] $summary"
send_notice "$summary" "$last_channel" "$last_to"
state_json="$(jq --arg key "$session_key" --argjson now "$now" '.[$key].lastAlertAt=$now' <<<"$state_json")"
printf '%s\n' "$state_json" > "$state_file"