Spaces:
Paused
Paused
| set -e | |
| echo "[boot] Creating 10 GB swap..." | |
| fallocate -l 10G /swapfile 2>/dev/null || dd if=/dev/zero of=/swapfile bs=1M count=10240 2>/dev/null | |
| chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile | |
| echo "[boot] Pulling OpenClaw state..." | |
| python3 -c " | |
| import sys, os; sys.path.insert(0, '/app') | |
| HF_TOKEN = os.environ.get('HF_TOKEN', '') | |
| DATASET_REPO = os.environ.get('OPENCLAW_DATASET_REPO', '') | |
| if HF_TOKEN and DATASET_REPO: | |
| from huggingface_hub import hf_hub_download | |
| from huggingface_hub.utils import EntryNotFoundError | |
| for fname in ['openclaw.json', 'SOUL.md']: | |
| try: | |
| hf_hub_download(repo_id=DATASET_REPO, filename=f'openclaw/{fname}', | |
| repo_type='dataset', token=HF_TOKEN, | |
| local_dir='/root', local_dir_use_symlinks=False) | |
| except EntryNotFoundError: pass | |
| except Exception as e: print(f' {e}') | |
| " | |
| echo "[boot] Configuring OpenClaw..." | |
| mkdir -p ~/.openclaw | |
| cat > ~/.openclaw/openclaw.json << JSONEOF | |
| { | |
| "gateway": {"port": 8080, "bind": "0.0.0.0"}, | |
| "identity": {"name": "YT Pipeline Assistant"}, | |
| "channels": { | |
| "telegram": { | |
| "enabled": true, | |
| "botToken": "${TELEGRAM_BOT_TOKEN}", | |
| "dmPolicy": "pairing" | |
| } | |
| }, | |
| "models": { | |
| "providers": { | |
| "ollama": { | |
| "baseUrl": "http://127.0.0.1:11434/v1", | |
| "apiKey": "ollama-local", | |
| "api": "openai-chat", | |
| "models": [ | |
| { | |
| "id": "deepseek-r1-70b", | |
| "name": "DeepSeek R1 Distill Llama 70B IQ2_XS", | |
| "contextWindow": 131072, | |
| "maxTokens": 8192 | |
| } | |
| ] | |
| } | |
| } | |
| }, | |
| "agents": { | |
| "defaults": { | |
| "model": {"primary": "ollama/deepseek-r1-70b"}, | |
| "workspace": "/app/yt-flow" | |
| } | |
| } | |
| } | |
| JSONEOF | |
| [ -f /app/SOUL.md ] && cp /app/SOUL.md ~/.openclaw/SOUL.md | |
| git config --global user.name "YT Pipeline Bot" | |
| git config --global user.email "yt-pipe-bot@hf.space" | |
| git clone https://arshitmalik:${HF_TOKEN}@huggingface.co/spaces/arshitmalik/yt-flow /app/yt-flow 2>/dev/null || true | |
| # Backup cron | |
| cat > /tmp/backup.sh << 'CRONEOF' | |
| #!/bin/bash | |
| python3 -c " | |
| import os, sys; sys.path.insert(0, '/app') | |
| HF_TOKEN = os.environ.get('HF_TOKEN', '') | |
| DATASET_REPO = os.environ.get('OPENCLAW_DATASET_REPO', '') | |
| if not HF_TOKEN or not DATASET_REPO: sys.exit(0) | |
| from huggingface_hub import HfApi | |
| api = HfApi(token=HF_TOKEN) | |
| from pathlib import Path | |
| for f in Path('/root/.openclaw').glob('*'): | |
| if f.is_file(): | |
| try: | |
| api.upload_file( | |
| path_or_fileobj=str(f), | |
| path_in_repo=f'openclaw/{f.name}', | |
| repo_id=DATASET_REPO, | |
| repo_type='dataset' | |
| ) | |
| except Exception as e: pass | |
| " 2>/dev/null | |
| CRONEOF | |
| chmod +x /tmp/backup.sh | |
| echo "*/15 * * * * /tmp/backup.sh" | crontab - | |
| # Temporary health server (keeps Space alive during setup) | |
| python3 -c " | |
| from http.server import HTTPServer, BaseHTTPRequestHandler | |
| class H(BaseHTTPRequestHandler): | |
| def do_GET(self): | |
| self.send_response(200); self.end_headers(); self.wfile.write(b'ok') | |
| HTTPServer(('0.0.0.0', 8080), H).serve_forever() | |
| " & | |
| HEALTH_PID=$! | |
| echo "[boot] Starting nginx..." | |
| nginx | |
| echo "[boot] Starting Ollama..." | |
| export OLLAMA_FLASH_ATTENTION=1 | |
| export OLLAMA_KV_CACHE_TYPE=q4_0 | |
| OLLAMA_HOST=127.0.0.1 OLLAMA_NUM_PARALLEL=1 OLLAMA_MAX_LOADED_MODELS=1 ollama serve & | |
| for i in $(seq 1 30); do | |
| if curl -sf http://127.0.0.1:11434/api/tags > /dev/null 2>&1; then | |
| echo "[boot] Ollama ready after ${i}s"; break | |
| fi | |
| sleep 2 | |
| done | |
| echo "[boot] Building custom 70B IQ2_XS model (~3 min)..." | |
| python3 << PYEOF | |
| import subprocess, sys, os | |
| from pathlib import Path | |
| from huggingface_hub import hf_hub_download | |
| gguf_path = hf_hub_download( | |
| repo_id="bartowski/DeepSeek-R1-Distill-Llama-70B-GGUF", | |
| filename="DeepSeek-R1-Distill-Llama-70B-IQ2_XS.gguf", | |
| local_dir="/tmp/gguf", | |
| resume_download=True, | |
| token=os.environ.get("HF_TOKEN", None) | |
| ) | |
| modelfile = f"""FROM {gguf_path} | |
| TEMPLATE \"\"\"<|begin▁of▁sentence|>{{ .System }} | |
| {{ .Prompt }}<|end▁of▁sentence|> | |
| <|begin▁of▁sentence|>assistant | |
| \"\"\" | |
| PARAMETER stop "<|begin▁of▁sentence|>" | |
| PARAMETER stop "<|end▁of▁sentence|>" | |
| PARAMETER num_ctx 131072 | |
| PARAMETER num_predict 8192 | |
| """ | |
| (Path("/tmp") / "Modelfile").write_text(modelfile) | |
| subprocess.run(["ollama", "create", "deepseek-r1-70b", "-f", "/tmp/Modelfile"], check=True) | |
| Path(gguf_path).unlink() | |
| PYEOF | |
| # Kill temp health server, start OpenClaw | |
| kill $HEALTH_PID 2>/dev/null | |
| echo "[boot] Starting OpenClaw gateway..." | |
| openclaw gateway & | |
| OPENCLAW_PID=$! | |
| echo "[boot] Deployment complete. PID: $OPENCLAW_PID" | |
| wait $OPENCLAW_PID 2>/dev/null | |
| sleep infinity | |