Spaces:
Running
Running
| set -e | |
| BOOT_START=$(date +%s) | |
| echo "[entrypoint] HermesFace β Hermes Agent on HuggingFace Spaces" | |
| echo "[entrypoint] ====================================================" | |
| HERMES_HOME="/opt/data" | |
| INSTALL_DIR="/opt/hermes" | |
| # ββ DNS pre-resolution (background β non-blocking) ββββββββββββββββββββββββ | |
| echo "[entrypoint] Starting DNS resolution in background..." | |
| python3 /opt/data/scripts/dns-resolve.py /tmp/dns-resolved.json 2>&1 & | |
| DNS_PID=$! | |
| echo "[entrypoint] DNS resolver PID: $DNS_PID" | |
| # Enable Node.js DNS fix preload for playwright / whatsapp-bridge / web build. | |
| export NODE_OPTIONS="${NODE_OPTIONS:+$NODE_OPTIONS }--require /opt/data/scripts/dns-fix.cjs" | |
| # ββ Activate virtual environment βββββββββββββββββββββββββββββββββββββββββ | |
| if [ -f "${INSTALL_DIR}/.venv/bin/activate" ]; then | |
| source "${INSTALL_DIR}/.venv/bin/activate" | |
| echo "[entrypoint] Activated venv: $(which python3)" | |
| fi | |
| # ββ Ensure data directories ββββββββββββββββββββββββββββββββββββββββββββββ | |
| mkdir -p "$HERMES_HOME"/{cron,sessions,logs,hooks,memories,skills,skins,plans,workspace,home} | |
| # ββ Bootstrap config files βββββββββββββββββββββββββββββββββββββββββββββββ | |
| if [ ! -f "$HERMES_HOME/.env" ] && [ -f "$INSTALL_DIR/.env.example" ]; then | |
| cp "$INSTALL_DIR/.env.example" "$HERMES_HOME/.env" | |
| echo "[entrypoint] Created .env from example" | |
| fi | |
| if [ ! -f "$HERMES_HOME/config.yaml" ] && [ -f "$INSTALL_DIR/cli-config.yaml.example" ]; then | |
| cp "$INSTALL_DIR/cli-config.yaml.example" "$HERMES_HOME/config.yaml" | |
| echo "[entrypoint] Created config.yaml from example" | |
| fi | |
| if [ ! -f "$HERMES_HOME/SOUL.md" ] && [ -f "$INSTALL_DIR/docker/SOUL.md" ]; then | |
| cp "$INSTALL_DIR/docker/SOUL.md" "$HERMES_HOME/SOUL.md" | |
| echo "[entrypoint] Created SOUL.md from template" | |
| fi | |
| # ββ Inject HF secrets into Hermes internal .env ββββββββββββββββββββββββββ | |
| # This makes dashboard auth and custom providers work on a public Space. | |
| touch "$HERMES_HOME/.env" | |
| # Upsert secrets instead of appending duplicate values on every restart. | |
| upsert_env() { | |
| local key="$1" | |
| local value="$2" | |
| [ -n "$value" ] || return 0 | |
| local tmp | |
| tmp="$(mktemp)" | |
| grep -v "^${key}=" "$HERMES_HOME/.env" > "$tmp" || true | |
| printf '%s=%s\n' "$key" "$value" >> "$tmp" | |
| mv "$tmp" "$HERMES_HOME/.env" | |
| } | |
| upsert_env HERMES_DASHBOARD_BASIC_AUTH_USERNAME "${HERMES_DASHBOARD_BASIC_AUTH_USERNAME:-admin}" | |
| upsert_env HERMES_DASHBOARD_BASIC_AUTH_PASSWORD "${HERMES_DASHBOARD_BASIC_AUTH_PASSWORD:-}" | |
| upsert_env HERMES_DASHBOARD_BASIC_AUTH_SECRET "${HERMES_DASHBOARD_BASIC_AUTH_SECRET:-}" | |
| upsert_env FREEMODEL_API_KEY "${FREEMODEL_API_KEY:-}" | |
| chmod 600 "$HERMES_HOME/.env" | |
| echo "[entrypoint] Dashboard auth and provider secrets injected into Hermes .env" | |
| # Free in-container keepalive. This prevents normal inactivity sleep while the | |
| # current container is alive; forced HF infrastructure rebuilds are handled by | |
| # the repo-persisted config + Space secrets on the next boot. | |
| KEEPALIVE_INTERVAL="${KEEPALIVE_INTERVAL:-900}" | |
| ( | |
| while true; do | |
| sleep "$KEEPALIVE_INTERVAL" | |
| code="$(curl -L -sS -o /dev/null -w '%{http_code}' "http://127.0.0.1:7860/" || true)" | |
| echo "[keepalive] local dashboard HTTP ${code:-000}" | |
| done | |
| ) & | |
| echo "[entrypoint] Keepalive started (interval=${KEEPALIVE_INTERVAL}s)" | |
| # ββ Sync bundled skills ββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| if [ -d "$INSTALL_DIR/skills" ] && [ -f "$INSTALL_DIR/tools/skills_sync.py" ]; then | |
| python3 "$INSTALL_DIR/tools/skills_sync.py" 2>&1 || echo "[entrypoint] Skills sync skipped" | |
| fi | |
| # ββ Build artifacts check ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| echo "[entrypoint] Build artifacts check:" | |
| test -f "$INSTALL_DIR/run_agent.py" && echo " OK run_agent.py" || echo " INFO: run_agent.py not found" | |
| test -f "$INSTALL_DIR/gateway/run.py" && echo " OK gateway/run.py" || echo " INFO: gateway/run.py not found" | |
| test -d "$INSTALL_DIR/web" && echo " OK web/ dashboard" || echo " INFO: web/ not found" | |
| command -v hermes >/dev/null 2>&1 && echo " OK hermes CLI: $(which hermes)" || echo " INFO: hermes CLI not in PATH" | |
| # ββ Create logs ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| mkdir -p /opt/data/logs | |
| touch /opt/data/logs/app.log | |
| ENTRYPOINT_END=$(date +%s) | |
| echo "[TIMER] Entrypoint (before sync_hf.py): $((ENTRYPOINT_END - BOOT_START))s" | |
| # ββ Start Hermes via sync_hf.py βββββββββββββββββββββββββββββββββββββββββββ | |
| # ββ VLESS proxy for Telegram (optional; requires VLESS_UUID secret) ββββββ | |
| if [ -f /opt/data/scripts/start_vless_proxy.sh ]; then | |
| echo "[entrypoint] Setting up VLESS proxy for Telegram..." | |
| # shellcheck disable=SC1091 | |
| source /opt/data/scripts/start_vless_proxy.sh || echo "[entrypoint] VLESS setup failed (non-fatal)" | |
| fi | |
| echo "[entrypoint] Starting Hermes Agent via sync_hf.py..." | |
| exec python3 -u /opt/data/scripts/sync_hf.py |