Spaces:
Runtime error
Runtime error
File size: 4,356 Bytes
09eb9d4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | #!/bin/bash
# Centralized Logging Configuration (Bug #18)
export LOG_LEVEL=${LOG_LEVEL:-"info"}
export LOG_FILE=${LOG_FILE:-"/app/verdant_claw.log"}
# Mask sensitive env vars in logs (Bug #13)
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 (Bug #12)
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 (Bug #9)
# Supports multi-key rotation: "nvidia_2" β NVIDIA_API_KEY_2
if [ -n "$API_KEYS_JSON" ]; then
log "Parsing API keys from JSON..."
# Primary keys
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')
# Rotation keys (nvidia_2, openai_2, etc.)
for provider in nvidia openai anthropic google groq; do
for i in $(seq 2 5); do
val=$(echo $API_KEYS_JSON | jq -r ".${provider}_${i} // empty")
if [ -n "$val" ] && [ "$val" != "null" ]; then
envname=$(echo "${provider}_API_KEY_${i}" | tr '[:lower:]' '[:upper:]')
export "$envname=$val"
log "β Loaded rotation key: $envname"
fi
done
done
log "β API keys loaded from JSON"
else
log "β οΈ WARNING: API_KEYS_JSON not set!"
fi
# Function to start service with retry (Bug #15)
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 (Bug #4)
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
# Locate memgraph binary (common paths in memgraph-mage)
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_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 alternate port (7861)
log "Starting 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 Marimo UI on port 7860..."
# Launch Marimo as the primary UI (port 7860 for HF Spaces healthcheck)
cd /app
nohup marimo run /app/app.py --host 0.0.0.0 --port 7860 --headless > /tmp/marimo.log 2>&1 &
MARIMO_PID=$!
sleep 3
if ps -p $MARIMO_PID > /dev/null; then
log "β Marimo started (PID: $MARIMO_PID)"
log " Marimo logs: /tmp/marimo.log"
else
log "β ERROR: Marimo failed to start!"
cat /tmp/marimo.log
exit 1
fi
# Start Pi Agent in background with EOF persistence fix
log "Starting Pi Agent in background..."
cd /app/mom-infra
start_with_retry "Pi Agent" "bash -c 'tail -f /dev/null | npm run pi -- --mode rpc --extensions /app/agent-pi/pi-extensions --skills /app/agent-pi/skills --prompts /app/agent-pi/commands'" || log "Pi Agent finished or failed."
log "All services active!"
log " - Memgraph: port 7687"
log " - ZeroClaw: gateway"
log " - OmniRoute: port 20128"
log " - Graph Viewer: port 7861"
log " - Marimo UI: port 7860 (primary)"
log " - Pi Agent: Background RPC"
# Keep container alive by waiting for all background processes
log "Holding container open. Access the UI at https://your-space.hf.space"
wait
|