#!/usr/bin/env bash # agent-mode.sh — flip EVERY agent on the Uno Q between cloud and offline. # # cloud (default, workshop): every agent → anthropic.max (claude-sonnet-5), # full tool set (risk_profile=default), full context (runtime=unoq). # Nothing feels broken; the on-board fallback is NOT in the way. # offline (resilience demo): every agent → llamacpp.local (on-board Qwen), # lean tools (risk_profile=demo) + lean context (runtime=offline) so # the 0.5B is actually usable. This is the fallback you enable on purpose. # # Usage: ./agent-mode.sh [cloud|offline] # Env: SERIAL (default 65301572) # # Restart note: kills the daemon so the supervisor relaunches it with the new # config. Cloud mode needs the Max token in the supervisor's env — if it's not # there (e.g. after a bare reboot), run deploy/uno-q/recover.sh first. set -u MODE="${1:-cloud}" SERIAL="${SERIAL:-65301572}" CFG=/home/arduino/.zeroclaw/config.toml S(){ adb -s "$SERIAL" shell "$@"; } case "$MODE" in cloud) PROV="anthropic.max"; RISK="default"; RT="unoq" ;; offline) PROV="llamacpp.local"; RISK="demo"; RT="offline" ;; *) echo "usage: $0 [cloud|offline]"; exit 1 ;; esac echo "→ setting ALL agents to: provider=$PROV risk=$RISK runtime=$RT" adb -s "$SERIAL" get-state >/dev/null 2>&1 || { echo "✗ board $SERIAL not attached"; exit 1; } S "cp -f $CFG ${CFG}.pre-${MODE}.bak" # Rewrite every top-level [agents.] block (not its .sub-tables). S "python3 - <<'PY' import re cfg='$CFG'; prov='$PROV'; risk='$RISK'; rt='$RT' hdr=re.compile(r'^\[agents\.[A-Za-z0-9_]+\]\$') out=[]; ina=False for ln in open(cfg).read().split('\n'): if hdr.match(ln): ina=True elif ln.startswith('['): ina=False if ina: if re.match(r'^\s*model_provider\s*=', ln): ln='model_provider = \"%s\"'%prov elif re.match(r'^\s*risk_profile\s*=', ln): ln='risk_profile = \"%s\"'%risk elif re.match(r'^\s*runtime_profile\s*=', ln): ln='runtime_profile = \"%s\"'%rt out.append(ln) open(cfg,'w').write('\n'.join(out)) print('rewrote agent blocks') PY" echo "→ restarting daemon (supervisor relaunches with new config)…" S 'for p in $(ps -C zeroclaw -o pid= 2>/dev/null); do kill -9 $p 2>/dev/null; done' for i in $(seq 1 15); do sleep 4 S 'curl -sf -m3 http://127.0.0.1:8080/health >/dev/null 2>&1' && break printf '.' done; echo echo "=== agents now ===" S "awk '/^\[agents\.[A-Za-z0-9_]+\]\$/{a=substr(\$0,9,length(\$0)-9)} /^model_provider/{print a\": \"\$3}' $CFG" if [ "$MODE" = cloud ]; then N=$(S 'P=$(pgrep -f "[z]eroclaw daemon" | head -1); cat /proc/$P/environ 2>/dev/null | tr "\0" "\n" | grep -c "ANTHROPIC_OAUTH_TOKEN"') [ "${N:-0}" -ge 1 ] && echo "✓ cloud token present in daemon env" \ || echo "✗ cloud token NOT in daemon env — run deploy/uno-q/recover.sh (with ANTHROPIC_OAUTH_TOKEN exported)" fi echo "done ($MODE)."