Switch to create-per-user pattern via copy_files
Browse files- bootstrap.sh +49 -17
bootstrap.sh
CHANGED
|
@@ -2,20 +2,22 @@
|
|
| 2 |
# ============================================================================
|
| 3 |
# Hermes Agent on a Bucket β one-shot bootstrap
|
| 4 |
# ============================================================================
|
| 5 |
-
#
|
| 6 |
-
#
|
|
|
|
| 7 |
#
|
| 8 |
# bash <(curl -fsSL https://huggingface.co/merve/hermes-agent-bootstrap/resolve/main/bootstrap.sh)
|
| 9 |
#
|
| 10 |
# What it touches:
|
| 11 |
-
#
|
| 12 |
-
# ~/
|
| 13 |
-
# ~/.hermes
|
|
|
|
| 14 |
# ~/.local/bin/{hf,hermes,hf-mount} β installed CLIs
|
| 15 |
# ============================================================================
|
| 16 |
set -euo pipefail
|
| 17 |
|
| 18 |
-
|
| 19 |
MOUNT="$HOME/hermes-bucket"
|
| 20 |
SECRETS="$HOME/.hermes-secrets.env"
|
| 21 |
|
|
@@ -49,13 +51,42 @@ if ! hf auth whoami >/dev/null 2>&1; then
|
|
| 49 |
echo " hf auth login"
|
| 50 |
exit 1
|
| 51 |
fi
|
| 52 |
-
HF_USER="$(hf auth whoami 2>/dev/null |
|
|
|
|
| 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 |
-
#
|
| 59 |
# ----------------------------------------------------------------------------
|
| 60 |
if ! command -v hf-mount >/dev/null 2>&1; then
|
| 61 |
say "Installing hf-mount..."
|
|
@@ -64,7 +95,7 @@ fi
|
|
| 64 |
ok "hf-mount: $(command -v hf-mount)"
|
| 65 |
|
| 66 |
# ----------------------------------------------------------------------------
|
| 67 |
-
#
|
| 68 |
# ----------------------------------------------------------------------------
|
| 69 |
mkdir -p "$MOUNT"
|
| 70 |
if hf-mount status 2>/dev/null | grep -q "$MOUNT"; then
|
|
@@ -76,7 +107,7 @@ else
|
|
| 76 |
fi
|
| 77 |
|
| 78 |
# ----------------------------------------------------------------------------
|
| 79 |
-
#
|
| 80 |
# ----------------------------------------------------------------------------
|
| 81 |
if ! command -v hermes >/dev/null 2>&1; then
|
| 82 |
say "Installing Hermes Agent (this takes a minute)..."
|
|
@@ -86,7 +117,7 @@ fi
|
|
| 86 |
ok "Hermes: $(command -v hermes)"
|
| 87 |
|
| 88 |
# ----------------------------------------------------------------------------
|
| 89 |
-
#
|
| 90 |
# ----------------------------------------------------------------------------
|
| 91 |
printf "\n${C}Telegram setup${N}\n"
|
| 92 |
|
|
@@ -131,7 +162,7 @@ except Exception:
|
|
| 131 |
fi
|
| 132 |
|
| 133 |
# ----------------------------------------------------------------------------
|
| 134 |
-
#
|
| 135 |
# ----------------------------------------------------------------------------
|
| 136 |
umask 077
|
| 137 |
cat > "$SECRETS" <<EOF
|
|
@@ -145,7 +176,7 @@ chmod 600 "$SECRETS"
|
|
| 145 |
ok "Secrets saved to $SECRETS (mode 600)"
|
| 146 |
|
| 147 |
# ----------------------------------------------------------------------------
|
| 148 |
-
#
|
| 149 |
# ----------------------------------------------------------------------------
|
| 150 |
SHELL_NAME="${SHELL##*/}"
|
| 151 |
case "$SHELL_NAME" in
|
|
@@ -167,15 +198,16 @@ else
|
|
| 167 |
fi
|
| 168 |
|
| 169 |
# ----------------------------------------------------------------------------
|
| 170 |
-
#
|
| 171 |
# ----------------------------------------------------------------------------
|
| 172 |
cat <<EOF
|
| 173 |
|
| 174 |
${G}β Ready.${N}
|
| 175 |
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
|
|
|
| 179 |
|
| 180 |
${C}hermes-here${N} β chat in your terminal
|
| 181 |
${C}hermes-gateway${N} β start Telegram bot (talk from your phone)
|
|
|
|
| 2 |
# ============================================================================
|
| 3 |
# Hermes Agent on a Bucket β one-shot bootstrap
|
| 4 |
# ============================================================================
|
| 5 |
+
# Creates your own HF bucket from the merve/hermes-agent template, mounts it,
|
| 6 |
+
# installs Hermes, sets up Telegram, and launches the agent.
|
| 7 |
+
# Idempotent: re-runs are safe.
|
| 8 |
#
|
| 9 |
# bash <(curl -fsSL https://huggingface.co/merve/hermes-agent-bootstrap/resolve/main/bootstrap.sh)
|
| 10 |
#
|
| 11 |
# What it touches:
|
| 12 |
+
# <YOUR_HF_USERNAME>/hermes-agent β your personal bucket (created if missing)
|
| 13 |
+
# ~/hermes-bucket β local mount of your bucket
|
| 14 |
+
# ~/.hermes-secrets.env β your local secrets (mode 600, NEVER uploaded)
|
| 15 |
+
# ~/.hermes/ β Hermes code + venv
|
| 16 |
# ~/.local/bin/{hf,hermes,hf-mount} β installed CLIs
|
| 17 |
# ============================================================================
|
| 18 |
set -euo pipefail
|
| 19 |
|
| 20 |
+
TEMPLATE="merve/hermes-agent"
|
| 21 |
MOUNT="$HOME/hermes-bucket"
|
| 22 |
SECRETS="$HOME/.hermes-secrets.env"
|
| 23 |
|
|
|
|
| 51 |
echo " hf auth login"
|
| 52 |
exit 1
|
| 53 |
fi
|
| 54 |
+
HF_USER="$(hf auth whoami --format json 2>/dev/null | python3 -c 'import json,sys; print(json.load(sys.stdin).get("user",""))')"
|
| 55 |
+
[ -n "$HF_USER" ] || die "Couldn't determine your HF username from 'hf auth whoami'"
|
| 56 |
HF_TOKEN_VAL="$(python3 -c 'from huggingface_hub import get_token; print(get_token() or "")' 2>/dev/null || true)"
|
| 57 |
[ -n "$HF_TOKEN_VAL" ] || die "Couldn't read HF token from local cache"
|
| 58 |
ok "Hugging Face: logged in as $HF_USER"
|
| 59 |
|
| 60 |
+
BUCKET="$HF_USER/hermes-agent"
|
| 61 |
+
|
| 62 |
+
# ----------------------------------------------------------------------------
|
| 63 |
+
# 3. Your bucket β create if missing, copy template if empty
|
| 64 |
+
# ----------------------------------------------------------------------------
|
| 65 |
+
if hf buckets info "$BUCKET" >/dev/null 2>&1; then
|
| 66 |
+
ok "Bucket $BUCKET already exists"
|
| 67 |
+
else
|
| 68 |
+
say "Creating $BUCKET..."
|
| 69 |
+
hf buckets create "$BUCKET" --exist-ok >/dev/null
|
| 70 |
+
ok "Bucket created: https://huggingface.co/buckets/$BUCKET"
|
| 71 |
+
fi
|
| 72 |
+
|
| 73 |
+
FILE_COUNT="$(hf buckets list "$BUCKET" --recursive --quiet 2>/dev/null | wc -l | tr -d ' ')"
|
| 74 |
+
if [ "${FILE_COUNT:-0}" -lt 3 ]; then
|
| 75 |
+
say "Seeding $BUCKET from template $TEMPLATE (server-side copy, ~1s)..."
|
| 76 |
+
python3 - <<PY
|
| 77 |
+
from huggingface_hub import HfApi
|
| 78 |
+
HfApi().copy_files(
|
| 79 |
+
source="hf://buckets/$TEMPLATE/",
|
| 80 |
+
destination="hf://buckets/$BUCKET/",
|
| 81 |
+
)
|
| 82 |
+
PY
|
| 83 |
+
ok "Template copied into $BUCKET"
|
| 84 |
+
else
|
| 85 |
+
ok "$BUCKET already populated ($FILE_COUNT files) β skipping template copy"
|
| 86 |
+
fi
|
| 87 |
+
|
| 88 |
# ----------------------------------------------------------------------------
|
| 89 |
+
# 4. hf-mount
|
| 90 |
# ----------------------------------------------------------------------------
|
| 91 |
if ! command -v hf-mount >/dev/null 2>&1; then
|
| 92 |
say "Installing hf-mount..."
|
|
|
|
| 95 |
ok "hf-mount: $(command -v hf-mount)"
|
| 96 |
|
| 97 |
# ----------------------------------------------------------------------------
|
| 98 |
+
# 5. Mount your bucket
|
| 99 |
# ----------------------------------------------------------------------------
|
| 100 |
mkdir -p "$MOUNT"
|
| 101 |
if hf-mount status 2>/dev/null | grep -q "$MOUNT"; then
|
|
|
|
| 107 |
fi
|
| 108 |
|
| 109 |
# ----------------------------------------------------------------------------
|
| 110 |
+
# 6. Hermes Agent
|
| 111 |
# ----------------------------------------------------------------------------
|
| 112 |
if ! command -v hermes >/dev/null 2>&1; then
|
| 113 |
say "Installing Hermes Agent (this takes a minute)..."
|
|
|
|
| 117 |
ok "Hermes: $(command -v hermes)"
|
| 118 |
|
| 119 |
# ----------------------------------------------------------------------------
|
| 120 |
+
# 7. Telegram (required step)
|
| 121 |
# ----------------------------------------------------------------------------
|
| 122 |
printf "\n${C}Telegram setup${N}\n"
|
| 123 |
|
|
|
|
| 162 |
fi
|
| 163 |
|
| 164 |
# ----------------------------------------------------------------------------
|
| 165 |
+
# 8. Write secrets file (outside the bucket, mode 600)
|
| 166 |
# ----------------------------------------------------------------------------
|
| 167 |
umask 077
|
| 168 |
cat > "$SECRETS" <<EOF
|
|
|
|
| 176 |
ok "Secrets saved to $SECRETS (mode 600)"
|
| 177 |
|
| 178 |
# ----------------------------------------------------------------------------
|
| 179 |
+
# 9. Shell aliases
|
| 180 |
# ----------------------------------------------------------------------------
|
| 181 |
SHELL_NAME="${SHELL##*/}"
|
| 182 |
case "$SHELL_NAME" in
|
|
|
|
| 198 |
fi
|
| 199 |
|
| 200 |
# ----------------------------------------------------------------------------
|
| 201 |
+
# 10. Summary + launch
|
| 202 |
# ----------------------------------------------------------------------------
|
| 203 |
cat <<EOF
|
| 204 |
|
| 205 |
${G}β Ready.${N}
|
| 206 |
|
| 207 |
+
Your bucket: https://huggingface.co/buckets/$BUCKET
|
| 208 |
+
Mount: $MOUNT
|
| 209 |
+
Secrets: $SECRETS
|
| 210 |
+
Model: Qwen/Qwen3.6-35B-A3B (HF Inference Providers β deepinfra)
|
| 211 |
|
| 212 |
${C}hermes-here${N} β chat in your terminal
|
| 213 |
${C}hermes-gateway${N} β start Telegram bot (talk from your phone)
|