#!/bin/bash # Centralized Logging Configuration export LOG_LEVEL=${LOG_LEVEL:-"info"} export LOG_FILE=${LOG_FILE:-"/app/verdant_claw.log"} # Mask sensitive env vars in logs log() { local msg=$(echo "$1" | sed -E 's/(nvapi|sk|gsk)[a-zA-Z0-9]+/\1*****/g') echo "[$(date -u +"%Y-%m-%dT%H:%M:%SZ")] [$LOG_LEVEL] $msg" | tee -a $LOG_FILE } # Trap SIGTERM for graceful shutdown cleanup() { log "Shutting down services gracefully..." kill $(jobs -p) 2>/dev/null sleep 2 log "Shutdown complete" exit 0 } trap cleanup SIGTERM SIGINT # Parse API_KEYS_JSON secret if [ -n "$API_KEYS_JSON" ]; then log "Parsing API keys from JSON..." export NVIDIA_API_KEY=$(echo $API_KEYS_JSON | jq -r '.nvidia // empty') export OPENAI_API_KEY=$(echo $API_KEYS_JSON | jq -r '.openai // empty') export ANTHROPIC_API_KEY=$(echo $API_KEYS_JSON | jq -r '.anthropic // empty') export GOOGLE_API_KEY=$(echo $API_KEYS_JSON | jq -r '.google // empty') export GROQ_API_KEY=$(echo $API_KEYS_JSON | jq -r '.groq // empty') log "✓ API keys loaded from JSON" else log "⚠️ WARNING: API_KEYS_JSON not set!" fi # Function to start service with retry start_with_retry() { local name=$1 local cmd=$2 local max_attempts=3 for i in $(seq 1 $max_attempts); do log "Starting $name (attempt $i/$max_attempts)..." eval "$cmd" & local pid=$! sleep 5 if ps -p $pid > /dev/null; then log "✓ $name started (PID: $pid)" return 0 fi log "⚠️ $name failed to start, retrying..." done log "❌ ERROR: $name failed after $max_attempts attempts" return 1 } # Check if ports are available check_port() { local port=$1 if netstat -tlnp 2>/dev/null | grep -q ":$port"; then log "❌ ERROR: Port $port already in use!" return 1 fi return 0 } log "Verifying infrastructure ports..." for port in 7860 7861 7687 20128; do check_port $port || exit 1 done # 🚀 Start Services MEMGRAPH_BIN=$(command -v memgraph || echo "/usr/bin/memgraph") if [ ! -f "$MEMGRAPH_BIN" ]; then MEMGRAPH_BIN="/usr/lib/memgraph/memgraph" fi start_with_retry "Memgraph" "$MEMGRAPH_BIN --bolt-port 7687" || exit 1 # Start ZeroClaw on port 7862 export ZEROCLAW_PORT=7862 start_with_retry "ZeroClaw" "zeroclaw gateway" || exit 1 start_with_retry "OmniRoute" "node /app/scripts/omniroute.js --config /app/config/omniroute-masterfile.json --port 20128" || exit 1 # Start Graph Viewer on port 7861 GRAPH_VIEWER_PORT=7861 start_with_retry "Graph Viewer" "node /app/scripts/graph-viewer.js" || exit 1 log "All infrastructure ready! Launching Gradio UI on port 7860..." # Launch Gradio app (NOT Marimo) cd /app nohup python3 app.py > /tmp/gradio.log 2>&1 & GRADIO_PID=$! sleep 3 if ps -p $GRADIO_PID > /dev/null; then log "✓ Gradio started (PID: $GRADIO_PID)" log " Gradio logs: /tmp/gradio.log" else log "❌ ERROR: Gradio failed to start!" cat /tmp/gradio.log exit 1 fi log "All services active!" log " - Memgraph: port 7687" log " - ZeroClaw: port 7862" log " - OmniRoute: port 20128" log " - Graph Viewer: port 7861" log " - Gradio UI: port 7860 (primary)" # Keep container alive log "Holding container open. Access the UI at https://your-space.hf.space" wait