Add Hermes Agent bootstrap script
Browse files- bootstrap.sh +193 -0
bootstrap.sh
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
# ============================================================================
|
| 3 |
+
# Hermes Agent on a Bucket β one-shot bootstrap
|
| 4 |
+
# ============================================================================
|
| 5 |
+
# Mounts the merve/hermes-agent HF bucket, installs Hermes Agent, prompts for
|
| 6 |
+
# a Telegram bot token, and launches the agent. Idempotent: re-runs are safe.
|
| 7 |
+
#
|
| 8 |
+
# bash <(curl -fsSL https://huggingface.co/merve/hermes-agent-bootstrap/resolve/main/bootstrap.sh)
|
| 9 |
+
#
|
| 10 |
+
# What it touches:
|
| 11 |
+
# ~/hermes-bucket β mount point for the bucket
|
| 12 |
+
# ~/.hermes-secrets.env β your local secrets (HF_TOKEN, Telegram), NEVER uploaded
|
| 13 |
+
# ~/.hermes/ β Hermes code + venv
|
| 14 |
+
# ~/.local/bin/{hf,hermes,hf-mount} β installed CLIs
|
| 15 |
+
# ============================================================================
|
| 16 |
+
set -euo pipefail
|
| 17 |
+
|
| 18 |
+
BUCKET="merve/hermes-agent"
|
| 19 |
+
MOUNT="$HOME/hermes-bucket"
|
| 20 |
+
SECRETS="$HOME/.hermes-secrets.env"
|
| 21 |
+
|
| 22 |
+
G='\033[0;32m'; Y='\033[0;33m'; C='\033[0;36m'; R='\033[0;31m'; N='\033[0m'
|
| 23 |
+
say() { printf "${C}β${N} %s\n" "$*"; }
|
| 24 |
+
ok() { printf "${G}β${N} %s\n" "$*"; }
|
| 25 |
+
warn() { printf "${Y}!${N} %s\n" "$*"; }
|
| 26 |
+
die() { printf "${R}β${N} %s\n" "$*" >&2; exit 1; }
|
| 27 |
+
ask() { local __var=$1; shift; local __prompt="$*"; read -rp " $__prompt" "$__var" </dev/tty; }
|
| 28 |
+
|
| 29 |
+
export PATH="$HOME/.local/bin:$PATH"
|
| 30 |
+
|
| 31 |
+
printf "\n${C}β Hermes Agent β bucket bootstrap${N}\n\n"
|
| 32 |
+
|
| 33 |
+
# ----------------------------------------------------------------------------
|
| 34 |
+
# 1. hf CLI
|
| 35 |
+
# ----------------------------------------------------------------------------
|
| 36 |
+
if ! command -v hf >/dev/null 2>&1; then
|
| 37 |
+
say "Installing hf CLI..."
|
| 38 |
+
curl -LsSf https://hf.co/cli/install.sh | bash
|
| 39 |
+
export PATH="$HOME/.local/bin:$PATH"
|
| 40 |
+
fi
|
| 41 |
+
ok "hf CLI: $(command -v hf)"
|
| 42 |
+
|
| 43 |
+
# ----------------------------------------------------------------------------
|
| 44 |
+
# 2. Hugging Face login
|
| 45 |
+
# ----------------------------------------------------------------------------
|
| 46 |
+
if ! hf auth whoami >/dev/null 2>&1; then
|
| 47 |
+
warn "Not logged in to Hugging Face."
|
| 48 |
+
echo " Run this in another terminal, then re-run the bootstrap:"
|
| 49 |
+
echo " hf auth login"
|
| 50 |
+
exit 1
|
| 51 |
+
fi
|
| 52 |
+
HF_USER="$(hf auth whoami 2>/dev/null | head -1 | awk '{print $NF}')"
|
| 53 |
+
HF_TOKEN_VAL="$(python3 -c 'from huggingface_hub import get_token; print(get_token() or "")' 2>/dev/null || true)"
|
| 54 |
+
[ -n "$HF_TOKEN_VAL" ] || die "Couldn't read HF token from local cache"
|
| 55 |
+
ok "Hugging Face: logged in as $HF_USER"
|
| 56 |
+
|
| 57 |
+
# ----------------------------------------------------------------------------
|
| 58 |
+
# 3. hf-mount
|
| 59 |
+
# ----------------------------------------------------------------------------
|
| 60 |
+
if ! command -v hf-mount >/dev/null 2>&1; then
|
| 61 |
+
say "Installing hf-mount..."
|
| 62 |
+
curl -fsSL https://raw.githubusercontent.com/huggingface/hf-mount/main/install.sh | sh
|
| 63 |
+
fi
|
| 64 |
+
ok "hf-mount: $(command -v hf-mount)"
|
| 65 |
+
|
| 66 |
+
# ----------------------------------------------------------------------------
|
| 67 |
+
# 4. Mount the bucket
|
| 68 |
+
# ----------------------------------------------------------------------------
|
| 69 |
+
mkdir -p "$MOUNT"
|
| 70 |
+
if hf-mount status 2>/dev/null | grep -q "$MOUNT"; then
|
| 71 |
+
ok "Bucket already mounted at $MOUNT"
|
| 72 |
+
else
|
| 73 |
+
say "Mounting $BUCKET at $MOUNT..."
|
| 74 |
+
hf-mount start --hf-token "$HF_TOKEN_VAL" bucket "$BUCKET" "$MOUNT" >/dev/null
|
| 75 |
+
ok "Mounted $BUCKET β $MOUNT"
|
| 76 |
+
fi
|
| 77 |
+
|
| 78 |
+
# ----------------------------------------------------------------------------
|
| 79 |
+
# 5. Hermes Agent
|
| 80 |
+
# ----------------------------------------------------------------------------
|
| 81 |
+
if ! command -v hermes >/dev/null 2>&1; then
|
| 82 |
+
say "Installing Hermes Agent (this takes a minute)..."
|
| 83 |
+
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash -s -- --skip-setup --skip-browser >/dev/null
|
| 84 |
+
export PATH="$HOME/.local/bin:$PATH"
|
| 85 |
+
fi
|
| 86 |
+
ok "Hermes: $(command -v hermes)"
|
| 87 |
+
|
| 88 |
+
# ----------------------------------------------------------------------------
|
| 89 |
+
# 6. Telegram (required step)
|
| 90 |
+
# ----------------------------------------------------------------------------
|
| 91 |
+
printf "\n${C}Telegram setup${N}\n"
|
| 92 |
+
|
| 93 |
+
EXISTING_TG=""
|
| 94 |
+
if [ -f "$SECRETS" ] && grep -q "^TELEGRAM_BOT_TOKEN=" "$SECRETS"; then
|
| 95 |
+
EXISTING_TG="$(grep "^TELEGRAM_BOT_TOKEN=" "$SECRETS" | head -1 | cut -d= -f2-)"
|
| 96 |
+
fi
|
| 97 |
+
|
| 98 |
+
if [ -n "$EXISTING_TG" ]; then
|
| 99 |
+
ok "Telegram bot token already on disk ($SECRETS)"
|
| 100 |
+
TG_TOKEN="$EXISTING_TG"
|
| 101 |
+
USER_ID="$(grep "^TELEGRAM_ALLOWED_USERS=" "$SECRETS" 2>/dev/null | head -1 | cut -d= -f2- || true)"
|
| 102 |
+
else
|
| 103 |
+
echo " 1. Open Telegram, message @BotFather, send /newbot, follow the prompts."
|
| 104 |
+
echo " 2. Paste the bot token below (looks like 123456:ABC-DEF...)"
|
| 105 |
+
echo ""
|
| 106 |
+
ask TG_TOKEN "Telegram bot token: "
|
| 107 |
+
[ -n "$TG_TOKEN" ] || die "Telegram bot token required"
|
| 108 |
+
|
| 109 |
+
echo ""
|
| 110 |
+
echo " 3. Now open your bot in Telegram and send it any message β say \"hi\"."
|
| 111 |
+
ask __continue "Press Enter once you've messaged the bot: "
|
| 112 |
+
|
| 113 |
+
say "Looking up your Telegram user id from getUpdates..."
|
| 114 |
+
USER_ID="$(curl -s "https://api.telegram.org/bot${TG_TOKEN}/getUpdates" | python3 -c "
|
| 115 |
+
import json, sys
|
| 116 |
+
try:
|
| 117 |
+
d = json.load(sys.stdin)
|
| 118 |
+
msgs = [u.get('message') or u.get('edited_message') or u.get('channel_post') for u in d.get('result', [])]
|
| 119 |
+
ids = [str(m['from']['id']) for m in msgs if m and m.get('from', {}).get('id')]
|
| 120 |
+
print(ids[-1] if ids else '')
|
| 121 |
+
except Exception:
|
| 122 |
+
print('')
|
| 123 |
+
")"
|
| 124 |
+
if [ -n "$USER_ID" ]; then
|
| 125 |
+
ok "Detected your Telegram user id: $USER_ID"
|
| 126 |
+
else
|
| 127 |
+
warn "Couldn't auto-detect. Enter it manually."
|
| 128 |
+
ask USER_ID "Telegram numeric user id: "
|
| 129 |
+
[ -n "$USER_ID" ] || die "Telegram user id required"
|
| 130 |
+
fi
|
| 131 |
+
fi
|
| 132 |
+
|
| 133 |
+
# ----------------------------------------------------------------------------
|
| 134 |
+
# 7. Write secrets file (outside the bucket, mode 600)
|
| 135 |
+
# ----------------------------------------------------------------------------
|
| 136 |
+
umask 077
|
| 137 |
+
cat > "$SECRETS" <<EOF
|
| 138 |
+
# Hermes secrets β DO NOT commit, DO NOT put in the bucket
|
| 139 |
+
HF_TOKEN=$HF_TOKEN_VAL
|
| 140 |
+
TELEGRAM_BOT_TOKEN=$TG_TOKEN
|
| 141 |
+
TELEGRAM_ALLOWED_USERS=$USER_ID
|
| 142 |
+
TELEGRAM_HOME_CHANNEL=$USER_ID
|
| 143 |
+
EOF
|
| 144 |
+
chmod 600 "$SECRETS"
|
| 145 |
+
ok "Secrets saved to $SECRETS (mode 600)"
|
| 146 |
+
|
| 147 |
+
# ----------------------------------------------------------------------------
|
| 148 |
+
# 8. Shell aliases
|
| 149 |
+
# ----------------------------------------------------------------------------
|
| 150 |
+
SHELL_NAME="${SHELL##*/}"
|
| 151 |
+
case "$SHELL_NAME" in
|
| 152 |
+
zsh) SHELL_RC="$HOME/.zshrc" ;;
|
| 153 |
+
bash) SHELL_RC="$HOME/.bashrc" ;;
|
| 154 |
+
*) SHELL_RC="$HOME/.profile" ;;
|
| 155 |
+
esac
|
| 156 |
+
|
| 157 |
+
if ! grep -q "# hermes-bucket aliases" "$SHELL_RC" 2>/dev/null; then
|
| 158 |
+
cat >> "$SHELL_RC" <<EOF
|
| 159 |
+
|
| 160 |
+
# hermes-bucket aliases (added by bootstrap.sh)
|
| 161 |
+
alias hermes-here='HERMES_HOME=\$HOME/hermes-bucket bash -c "set -a; source \$HOME/.hermes-secrets.env; set +a; exec hermes"'
|
| 162 |
+
alias hermes-gateway='HERMES_HOME=\$HOME/hermes-bucket bash -c "set -a; source \$HOME/.hermes-secrets.env; set +a; exec hermes gateway start"'
|
| 163 |
+
EOF
|
| 164 |
+
ok "Added shell aliases to $SHELL_RC"
|
| 165 |
+
else
|
| 166 |
+
ok "Shell aliases already present in $SHELL_RC"
|
| 167 |
+
fi
|
| 168 |
+
|
| 169 |
+
# ----------------------------------------------------------------------------
|
| 170 |
+
# 9. Summary + launch
|
| 171 |
+
# ----------------------------------------------------------------------------
|
| 172 |
+
cat <<EOF
|
| 173 |
+
|
| 174 |
+
${G}β Ready.${N}
|
| 175 |
+
|
| 176 |
+
Mount: $MOUNT
|
| 177 |
+
Secrets: $SECRETS
|
| 178 |
+
Model: Qwen/Qwen3.6-35B-A3B (HF Inference Providers β deepinfra)
|
| 179 |
+
|
| 180 |
+
${C}hermes-here${N} β chat in your terminal
|
| 181 |
+
${C}hermes-gateway${N} β start Telegram bot (talk from your phone)
|
| 182 |
+
|
| 183 |
+
EOF
|
| 184 |
+
|
| 185 |
+
if [ -t 0 ] && [ -t 1 ]; then
|
| 186 |
+
say "Launching Hermes now..."
|
| 187 |
+
sleep 1
|
| 188 |
+
export HERMES_HOME="$MOUNT"
|
| 189 |
+
set -a; source "$SECRETS"; set +a
|
| 190 |
+
exec hermes
|
| 191 |
+
else
|
| 192 |
+
say "Run ${C}source $SHELL_RC${N} then ${C}hermes-here${N} to start chatting."
|
| 193 |
+
fi
|