#!/bin/bash set -e echo "🚀 Starting Vane on Hugging Face Spaces..." CONFIG_FILE="/app/config.toml" # ── Inject into config.toml ─────────────────────────────────────────────────── if [ -n "$SEARXNG_URL" ]; then echo "✅ SearXNG URL found — injecting into config..." sed -i "s|SEARXNG = \"\"|SEARXNG = \"$SEARXNG_URL\"|g" "$CONFIG_FILE" else echo "❌ ERROR: SEARXNG_URL secret is not set!" exit 1 fi if [ -n "$GROQ_API_KEY" ]; then sed -i "s|GROQ = \"\"|GROQ = \"$GROQ_API_KEY\"|g" "$CONFIG_FILE" fi if [ -n "$OPENAI_API_KEY" ]; then sed -i "s|OPENAI = \"\"|OPENAI = \"$OPENAI_API_KEY\"|g" "$CONFIG_FILE" fi if [ -n "$ANTHROPIC_API_KEY" ]; then sed -i "s|ANTHROPIC = \"\"|ANTHROPIC = \"$ANTHROPIC_API_KEY\"|g" "$CONFIG_FILE" fi if [ -n "$OLLAMA_URL" ]; then sed -i "s|OLLAMA = \"\"|OLLAMA = \"$OLLAMA_URL\"|g" "$CONFIG_FILE" fi if [ -z "$OPENAI_API_KEY" ] && [ -z "$GROQ_API_KEY" ] && [ -z "$ANTHROPIC_API_KEY" ] && [ -z "$OLLAMA_URL" ]; then echo "❌ ERROR: No LLM configured!" exit 1 fi # ── Determine provider + model ──────────────────────────────────────────────── if [ -n "$GROQ_API_KEY" ]; then PROVIDER="groq" API_KEY="$GROQ_API_KEY" MODEL="llama-3.1-8b-instant" elif [ -n "$OPENAI_API_KEY" ]; then PROVIDER="openai" API_KEY="$OPENAI_API_KEY" MODEL="gpt-4o-mini" elif [ -n "$ANTHROPIC_API_KEY" ]; then PROVIDER="anthropic" API_KEY="$ANTHROPIC_API_KEY" MODEL="claude-3-5-haiku-20241022" elif [ -n "$OLLAMA_URL" ]; then PROVIDER="ollama" API_KEY="$OLLAMA_URL" MODEL="qwen2.5:3b" fi # ── Restore DB from HF Dataset repo ────────────────────────────────────────── mkdir -p /app/data if [ -n "$HF_TOKEN" ] && [ -n "$HF_DATASET_REPO" ]; then echo "📥 Restoring DB from HF Dataset repo..." python3 -c " from huggingface_hub import hf_hub_download import shutil, os try: path = hf_hub_download( repo_id='$HF_DATASET_REPO', filename='vane.db', repo_type='dataset', token='$HF_TOKEN' ) os.makedirs('/app/data', exist_ok=True) shutil.copy(path, '/app/data/vane.db') print('✅ DB restored from HF Dataset!') except Exception as e: print(f'⚠️ No existing DB found, starting fresh: {e}') " else echo "⚠️ HF_TOKEN or HF_DATASET_REPO not set — storage will be ephemeral!" fi # ── Run DB migrations ───────────────────────────────────────────────────────── echo "🗄️ Running database migrations..." cd /app npx drizzle-kit migrate 2>/dev/null || echo "⚠️ Migration skipped" # ── Seed DB with correct key names ─────────────────────────────────────────── echo "🌱 Seeding database settings..." python3 -c " import sqlite3, os db_path = '/app/data/vane.db' if not os.path.exists(db_path): print('⚠️ DB not found, creating...') os.makedirs('/app/data', exist_ok=True) conn = sqlite3.connect(db_path) cur = conn.cursor() cur.execute('''CREATE TABLE IF NOT EXISTS settings ( key TEXT PRIMARY KEY, value TEXT )''') provider = '$PROVIDER' api_key = '$API_KEY' model = '$MODEL' searxng = '$SEARXNG_URL' ollama = os.environ.get('OLLAMA_URL', '') settings = [ ('setup_complete', 'true'), ('chatModelProvider', provider), ('chatModel', model), ('embeddingModelProvider', 'local'), ('embeddingModel', 'xenova/all-MiniLM-L6-v2'), ('defaultChatModelProvider', provider), ('defaultChatModel', model), ('defaultEmbeddingModelProvider', 'local'), ('defaultEmbeddingModel', 'xenova/all-MiniLM-L6-v2'), ('groqApiKey', os.environ.get('GROQ_API_KEY', '')), ('openaiApiKey', os.environ.get('OPENAI_API_KEY', '')), ('anthropicApiKey', os.environ.get('ANTHROPIC_API_KEY', '')), ('ollamaApiUrl', ollama), ('searxngUrl', searxng), ] for key, value in settings: cur.execute('INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)', (key, value)) conn.commit() print('✅ DB seeded with correct keys!') # Verify cur.execute('SELECT key, value FROM settings') for row in cur.fetchall(): k, v = row if 'key' in k.lower() or 'Key' in k: v = v[:8] + '...' if len(v) > 8 else v # mask keys print(f' {k} = {v}') conn.close() " # ── Write backup script ─────────────────────────────────────────────────────── cat > /backup.sh << 'BACKUPSCRIPT' #!/bin/bash echo "🔄 DB backup loop started..." while true; do sleep 600 if [ -f "/app/data/vane.db" ] && [ -n "$HF_TOKEN" ] && [ -n "$HF_DATASET_REPO" ]; then echo "💾 Backing up DB to HF Dataset..." python3 -c " from huggingface_hub import HfApi import os api = HfApi() try: api.upload_file( path_or_fileobj='/app/data/vane.db', path_in_repo='vane.db', repo_id=os.environ['HF_DATASET_REPO'], repo_type='dataset', token=os.environ['HF_TOKEN'] ) print('✅ DB backed up!') except Exception as e: print(f'❌ Backup failed: {e}') " fi done BACKUPSCRIPT chmod +x /backup.sh mkdir -p /var/log/supervisor echo "✅ All config done" echo "🔧 Starting services..." exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf