| #!/bin/bash |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| set -uo pipefail |
|
|
| echo "" |
| echo " ββββββββββββββββββββββββββββββββββββββββ" |
| echo " β π HomePilot HF Space β" |
| echo " β Private AI Β· Persistent Personas β" |
| echo " ββββββββββββββββββββββββββββββββββββββββ" |
| echo "" |
|
|
| |
| mkdir -p /tmp/ollama/models /tmp/homepilot/data /tmp/homepilot/uploads /tmp/homepilot/outputs |
| export OLLAMA_MODELS=/tmp/ollama/models |
| export HOME=/tmp |
|
|
| |
| export SQLITE_PATH=/tmp/homepilot/data/homepilot.db |
| export UPLOAD_DIR=/tmp/homepilot/uploads |
| export OUTPUT_DIR=/tmp/homepilot/outputs |
| export DEFAULT_PROVIDER=${DEFAULT_PROVIDER:-ollama} |
| export OLLAMA_BASE_URL=http://127.0.0.1:11434 |
| |
| |
| |
| |
| |
| if [ -z "${OLLAMA_MODEL:-}" ] && [ -n "${SPACE_ID:-}" ]; then |
| export OLLAMA_MODEL="qwen2.5:0.5b" |
| fi |
| export OLLAMA_MODEL=${OLLAMA_MODEL:-qwen2.5:1.5b} |
| |
| |
| |
| export OLLAMA_FALLBACK_MODELS=${OLLAMA_FALLBACK_MODELS:-qwen2.5:0.5b,llama3.2:1b,smollm2:360m} |
| export COMFY_BASE_URL="" |
| export MEDIA_BASE_URL="" |
| export AVATAR_SERVICE_URL="" |
| export CORS_ORIGINS="*" |
| export API_KEY=${API_KEY:-} |
|
|
| |
| echo "[1/4] Starting Ollama..." |
| ollama serve & |
| OLLAMA_PID=$! |
|
|
| OLLAMA_READY=false |
| for i in $(seq 1 60); do |
| if curl -sf http://127.0.0.1:11434/api/tags > /dev/null 2>&1; then |
| echo " β Ollama ready (${i}s)" |
| OLLAMA_READY=true |
| break |
| fi |
| sleep 1 |
| done |
|
|
| if [ "$OLLAMA_READY" != "true" ]; then |
| echo " β Ollama did not come up within 60s β continuing anyway" |
| echo " The UI setup wizard can retry the model pull after boot." |
| fi |
|
|
| |
| |
| |
| |
| |
| |
| pull_with_retries () { |
| local model="$1" |
| local tries=3 |
| for attempt in $(seq 1 "$tries"); do |
| echo " β Pulling ${model} (attempt ${attempt}/${tries})..." |
| if ollama pull "$model" 2>&1 | tail -3; then |
| echo " β ${model} pulled" |
| return 0 |
| fi |
| echo " β pull failed for ${model}" |
| sleep $((attempt * 2)) |
| done |
| return 1 |
| } |
|
|
| MODEL_OK=false |
| if [ "$OLLAMA_READY" = "true" ]; then |
| echo "[2/4] Checking model: ${OLLAMA_MODEL}..." |
| MODEL_CHECK=$(curl -sf http://127.0.0.1:11434/api/tags 2>/dev/null || echo '{"models":[]}') |
| if echo "$MODEL_CHECK" | grep -q "${OLLAMA_MODEL}"; then |
| echo " β Model ${OLLAMA_MODEL} already available" |
| MODEL_OK=true |
| else |
| |
| if pull_with_retries "$OLLAMA_MODEL"; then |
| MODEL_OK=true |
| else |
| echo " βͺ Trying fallback chain: ${OLLAMA_FALLBACK_MODELS}" |
| IFS=',' read -ra FALLBACKS <<< "$OLLAMA_FALLBACK_MODELS" |
| for fb in "${FALLBACKS[@]}"; do |
| fb=$(echo "$fb" | xargs) |
| [ -z "$fb" ] && continue |
| if pull_with_retries "$fb"; then |
| export OLLAMA_MODEL="$fb" |
| MODEL_OK=true |
| echo " βΉ Using fallback model: ${fb}" |
| break |
| fi |
| done |
| fi |
| fi |
|
|
| if [ "$MODEL_OK" != "true" ]; then |
| echo " β No model could be pulled. App will boot without a default." |
| echo " Users can pull a model later via the Models page or:" |
| echo " curl -X POST http://127.0.0.1:11434/api/pull -d '{\"name\":\"qwen2.5:1.5b\"}'" |
| fi |
| else |
| echo "[2/4] Skipping model pull β Ollama not ready." |
| fi |
|
|
| |
| |
| |
| |
| |
| |
| if [ "${MODEL_OK:-false}" = "true" ] && [ "${OLLAMA_WARMUP:-true}" = "true" ]; then |
| echo " Β· pre-warming runner (background)..." |
| ( |
| curl -sSf -X POST http://127.0.0.1:11434/api/chat \ |
| -H "Content-Type: application/json" \ |
| -d "{\"model\":\"${OLLAMA_MODEL}\",\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}],\"stream\":false,\"options\":{\"num_predict\":1}}" \ |
| > /dev/null 2>&1 || true |
| ) & |
| fi |
|
|
| |
| echo "[3/4] Importing Chata personas..." |
| MARKER="/tmp/homepilot/data/.personas_imported" |
| CHATA_PERSONAS_DIR="${CHATA_PERSONAS_DIR:-/app/chata-personas}" |
| if [ -f "$MARKER" ]; then |
| echo " β Already imported ($(cat "$MARKER"))" |
| else |
| |
| |
| |
| |
| EXTRA_ARGS="" |
| if [ -d "/app/custom-personas" ]; then EXTRA_ARGS="$EXTRA_ARGS /app/custom-personas"; fi |
| if [ -d "/app/shared-personas" ]; then EXTRA_ARGS="$EXTRA_ARGS /app/shared-personas"; fi |
| if python3 /app/auto_import_personas.py "$CHATA_PERSONAS_DIR" /tmp/homepilot/data $EXTRA_ARGS; then |
| echo "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$MARKER" |
| echo " β Personas imported" |
| else |
| echo " β Persona import reported an error β continuing" |
| fi |
| fi |
|
|
| |
| echo "[4/4] Starting HomePilot on :7860..." |
| echo "" |
| echo " ββββββββββββββββββββββββββββββββββββββββ" |
| echo " β Ready! β" |
| echo " β β" |
| echo " β App: / β" |
| echo " β Health: /health β" |
| echo " β API: /docs β" |
| echo " β Gallery: /community/registry β" |
| echo " β Chat: /v1/chat/completions β" |
| echo " ββββββββββββββββββββββββββββββββββββββββ" |
| echo "" |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| if [ "${ENABLE_PROJECT_BOOTSTRAP:-true}" = "true" ] \ |
| && [ -f /app/chata_project_bootstrap.py ]; then |
| ( |
| sleep 5 |
| for attempt in 1 2; do |
| python3 /app/chata_project_bootstrap.py \ |
| --personas-dir "${CHATA_PERSONAS_DIR:-/app/chata-personas}" \ |
| --api-base http://127.0.0.1:7860 \ |
| --marker /tmp/homepilot/data/.projects_bootstrapped \ |
| $([ "$attempt" -gt 1 ] && echo "--force") \ |
| && break |
| echo "[chata-bootstrap] retry in 30s..." |
| sleep 30 |
| done |
| ) 2>&1 | tee -a /tmp/homepilot/data/bootstrap.log & |
| fi |
|
|
| exec python3 /app/hf_wrapper.py |
|
|