File size: 3,214 Bytes
e8f044a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
#!/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