← back to Local Model Leaderboard Watch
review.sh
58 lines
#!/bin/bash
# Hourly local-model leaderboard watcher.
# The WRAPPER (this deterministic script) gathers LOCAL cluster state.
# The claude review then runs with NO shell/Bash — only WebSearch/WebFetch/Read/Write
# (research + report + gated recommendation). READ-ONLY: never downloads, never changes the cluster.
set -uo pipefail
DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
EXO_MODELS_DIR="${EXO_MODELS_DIR:-$HOME/.exo/models}"
TS="$(date '+%FT%T%z')"
echo "[$TS] === review start ===" >> "$DIR/data/run.log"
# 1) wrapper collects local state into a file for claude to READ (no Bash needed in the agent)
{
echo "# Local cluster state @ $TS"
echo "## Loaded exo model (curl :52415/state):"
curl -s -m8 http://127.0.0.1:52415/state 2>/dev/null \
| python3 -c "import json,sys
try:
d=json.load(sys.stdin); inst=d.get('instances',{})
print(list(inst.values())[0]['MlxRingInstance']['shardAssignments']['modelId'] if inst else 'none loaded')
except Exception as e: print('state-unreachable')" 2>/dev/null
echo "## Downloaded models (~/.exo/models):"
ls -la "$EXO_MODELS_DIR" 2>/dev/null | awk '{print $5, $NF}' | grep -viE '^\s*$|caches|\.$'
echo "## Hardware: 96GB M3 Ultra (primary) + 2x 32GB nodes; target = fits ~55GB weights single-node."
} > "$DIR/data/local-state.txt" 2>&1
# 2) claude reviews — NO Bash, NO Skill: research + read the state file + write report/recommendation
timeout 600 claude -p "$(cat "$DIR/review-prompt.md")" \
--allowedTools "WebSearch,WebFetch,Read,Write" \
>> "$DIR/data/run.log" 2>&1
rc=$?
# 3) DETERMINISTIC load of today's chosen model — ONLY if it's already downloaded.
# Never downloads: if model weights are missing or incomplete, we leave the current model and rely
# on the gated pending-approval memo. This is the wrapper's job, not the agent's.
CHOSEN="$(head -1 "$DIR/data/chosen-model.txt" 2>/dev/null | tr -d '[:space:]')"
if [ -n "$CHOSEN" ]; then
DNAME="$(printf '%s' "$CHOSEN" | sed 's#/#--#g')"
if python3 "$DIR/verify-model-weights.py" "$EXO_MODELS_DIR/$DNAME" >> "$DIR/data/run.log" 2>&1; then
LOADED="$(curl -s -m8 http://127.0.0.1:52415/state 2>/dev/null | python3 -c "import json,sys
try:
d=json.load(sys.stdin); i=d.get('instances',{})
print(list(i.values())[0]['MlxRingInstance']['shardAssignments']['modelId'] if i else '')
except: print('')" 2>/dev/null)"
if [ "$CHOSEN" != "$LOADED" ]; then
echo "[$TS] loading TODAY's chosen (on disk): $CHOSEN (was: ${LOADED:-none})" >> "$DIR/data/run.log"
curl -s -m600 http://127.0.0.1:52415/v1/chat/completions -H 'Content-Type: application/json' \
-d "{\"model\":\"$CHOSEN\",\"messages\":[{\"role\":\"user\",\"content\":\"ok\"}],\"max_tokens\":1}" >/dev/null 2>&1
echo "[$TS] chosen model load requested" >> "$DIR/data/run.log"
else
echo "[$TS] chosen $CHOSEN already loaded — no change" >> "$DIR/data/run.log"
fi
else
echo "[$TS] chosen $CHOSEN weights missing/incomplete — keeping current model; download is gated (see pending-approval)" >> "$DIR/data/run.log"
fi
fi
echo "[$TS] === review done (exit $rc) ===" >> "$DIR/data/run.log"