← back to Exo Keepalive

enable-exo-inference.sh

45 lines

#!/usr/bin/env bash
# enable-exo-inference.sh — run ON a node AFTER full Xcode is installed.
# Builds exo's pinned mlx fork (needs the Metal compiler from full Xcode.app),
# flips the keepalive runner to use the mlx extra, and restarts exo.
# Portable: uses $HOME/local user. Idempotent.
#
# PREREQ (Steve, once per machine — needs sudo, App Store):
#   1. App Store -> install Xcode (~15GB)
#   2. sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
#   3. sudo xcodebuild -license accept
#   Then run this script.
set -uo pipefail
UV="$(command -v uv || echo "$HOME/.local/bin/uv")"
KA="$HOME/Projects/exo-keepalive"; RUN="$KA/run-exo.sh"; UIDN="$(id -u)"

echo "== enable exo inference on $(hostname) (user $(whoami)) =="

# 0. gate: Metal toolchain must be present (full Xcode, not just CLT)
if ! xcrun -sdk macosx metal --version >/dev/null 2>&1; then
  echo "!! Metal compiler NOT found. Install full Xcode first, then:"
  echo "     sudo xcode-select -s /Applications/Xcode.app/Contents/Developer"
  echo "     sudo xcodebuild -license accept"
  exit 1
fi
echo "== Metal toolchain OK: $(xcrun -sdk macosx metal --version 2>&1 | head -1) =="

# 1. build exo's pinned mlx fork + inference deps (compiles Metal shaders; several min)
echo "== uv sync --extra mlx (building mlx fork; this takes a while) =="
( cd "$HOME/exo" && "$UV" sync --extra mlx ) || { echo "!! mlx build failed — check Xcode/Metal setup"; exit 1; }

# 2. flip the keepalive runner to use the mlx extra (so restarts keep inference)
if grep -q 'run exo ' "$RUN"; then
  sed -i '' 's#run exo #run --extra mlx exo #' "$RUN"
  echo "== runner now uses --extra mlx =="
fi

# 3. restart + verify daemon
launchctl kickstart -k "gui/$UIDN/com.steve.exo-keepalive" >/dev/null 2>&1
for i in $(seq 1 20); do
  [ "$(curl -s -o /dev/null -w '%{http_code}' -m3 http://localhost:52415/v1/models 2>/dev/null)" = "200" ] && \
    { echo "✅ exo daemon up with mlx inference enabled on $(hostname)"; exit 0; }
  sleep 6
done
echo "⚠️ daemon not up yet — check $KA/exo.log"; exit 1