#!/usr/bin/env bash # One-time setup for the Mac always-on daemon (Scenario 1): # Hermes (llama-server) + backend (autonomous) + collector, as launchd jobs. # # Prereqs you provide: # - llama.cpp built (llama-server on PATH, or pass LLAMA_SERVER=/path/to/llama-server) # - a Hermes GGUF (e.g. Hermes-3-Llama-3.1-8B Q4_K_M) -> pass MODEL_GGUF=/path # - Google OAuth: credentials.json (+ token.json after first auth) in the repo dir # - Full Disk Access for the python binary (the script prints how) # # Usage: # INGEST_TOKEN=... MODEL_GGUF=~/models/hermes-3-8b-q4.gguf ./scripts/setup_mac.sh set -euo pipefail REPO="$(cd "$(dirname "$0")/.." && pwd)" HOME_DIR="$HOME" PYTHON="${PYTHON:-$(command -v python3)}" LLAMA_SERVER="${LLAMA_SERVER:-$(command -v llama-server || true)}" MODEL_GGUF="${MODEL_GGUF:?set MODEL_GGUF=/path/to/hermes.gguf}" INGEST_TOKEN="${INGEST_TOKEN:?set INGEST_TOKEN=... (same value you use elsewhere)}" LA="$HOME_DIR/Library/LaunchAgents" [ -n "$LLAMA_SERVER" ] || { echo "llama-server not found; set LLAMA_SERVER=/path"; exit 1; } mkdir -p "$LA" "$HOME_DIR/.offgrid" "$HOME_DIR/Library/Logs" install_plist() { local name="$1" sed -e "s|__PYTHON__|$PYTHON|g" \ -e "s|__REPO__|$REPO|g" \ -e "s|__HOME__|$HOME_DIR|g" \ -e "s|__LLAMA_SERVER__|$LLAMA_SERVER|g" \ -e "s|__MODEL_GGUF__|$MODEL_GGUF|g" \ -e "s|__INGEST_TOKEN__|$INGEST_TOKEN|g" \ "$REPO/deploy/launchd/$name" > "$LA/$name" launchctl unload "$LA/$name" 2>/dev/null || true launchctl load "$LA/$name" echo "loaded $name" } "$PYTHON" -m pip install -q -r "$REPO/requirements-ci.txt" # runtime deps (no GPU model needed on Mac) install_plist com.offgrid.hermes.plist install_plist com.offgrid.backend.plist install_plist com.offgrid.collector.plist cat < llama-server (Hermes) on :8080 com.offgrid.backend -> Gradio UI + /agent + /ingest on :7860 (AUTONOMOUS, Hermes brain) com.offgrid.collector -> reads chat.db -> /ingest ONE MANUAL STEP: grant Full Disk Access to the python binary so the collector can read chat.db: System Settings > Privacy & Security > Full Disk Access > + -> $PYTHON Then: launchctl kickstart -k gui/\$(id -u)/com.offgrid.collector Dashboard: http://127.0.0.1:7860 (Activity = live runs, Memory = what it learned) Logs: ~/Library/Logs/offgrid-*.log Triggers on YOUR sent/accepted iMessages (TRIGGER_ON=outgoing). Set TRIGGER_ON=any to widen. EOF