Spaces:
Sleeping
Sleeping
File size: 5,197 Bytes
b26f525 c0963c0 b26f525 c0963c0 b26f525 c0963c0 b26f525 c0963c0 b26f525 c0963c0 b26f525 c0963c0 b26f525 a262fdc b26f525 c0963c0 b26f525 c0963c0 b26f525 c0963c0 b26f525 23039bf c0963c0 f7cacc8 fa8d364 c0963c0 b26f525 c0963c0 a262fdc b26f525 a262fdc a6b7d4e 432fbd9 88904b4 6c137b9 2d09bf1 8a7082c 88904b4 8a7082c 2d09bf1 8a7082c 88904b4 8a7082c 7e7b0d5 a262fdc 7e7b0d5 a262fdc 2cf0f39 a262fdc 2cf0f39 a262fdc c0963c0 a262fdc c0963c0 a262fdc | 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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | #!/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 7862; 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 42617 (NOT 7860 - Marimo needs that)
# Use environment variable to set port
export ZEROCLAW_GATEWAY_PORT=42617
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 Marimo UI on port 7860..."
# Setup Ollama config (proxy to ZeroClaw)
mkdir -p /home/node/.ollama
cp /app/ollama-config.json /home/node/.ollama/config.json 2>/dev/null || true
log "β Ollama configured to proxy to ZeroClaw"
# Start Ollama serve (in background)
log "Starting Ollama..."
nohup ollama serve > /tmp/ollama.log 2>&1 &
OLLAMA_PID=$!
sleep 3
if ps -p $OLLAMA_PID > /dev/null; then
log "β Ollama started (PID: $OLLAMA_PID)"
# Pull a default model
log "Pulling default model (this may take a minute)..."
ollama pull llama3.2 || log "β οΈ Could not pull model, will use ZeroClaw models"
else
log "β οΈ Ollama failed to start"
fi
# Setup Marimo config (pre-configured with Ollama as AI provider)
mkdir -p /home/node/.config/marimo
cat > /home/node/.config/marimo/marimo.toml << 'TOML'
[ai]
enabled = true
[ai.providers.ollama]
name = "Ollama"
base_url = "http://localhost:11434/v1"
api_key = "ollama-local-key"
[[ai.models]]
provider = "ollama"
model = "zeroclaw/default"
TOML
log "β Marimo AI config created with Ollama provider"
# Initialize Pi (accepts config, creates necessary files)
log "Initializing Pi agent..."
echo "y" | pi --mode rpc --extensions /app/agent-pi/pi-extensions --skills /app/agent-pi/skills --prompts /app/agent-pi/commands </dev/null > /tmp/pi-init.log 2>&1 || true
sleep 2
# Start pi-acp for ACP support (Marimo AI integration) through stdio-to-ws bridge
# Name it "opencode" so Marimo recognizes it!
log "Starting pi-acp ACP server via stdio-to-ws bridge (as 'opencode')..."
nohup npx stdio-to-ws "pi-acp --terminal-login" --port 3017 --name "opencode" > /tmp/pi-acp.log 2>&1 &
PI_ACP_PID=$!
sleep 3
if ps -p $PI_ACP_PID > /dev/null; then
log "β pi-acp started on ws://localhost:3017 as 'opencode' (PID: $PI_ACP_PID)"
else
log "β οΈ pi-acp failed to start, check /tmp/pi-acp.log"
cat /tmp/pi-acp.log
fi
# Launch Marimo in EDIT MODE (not app mode)
cd /app
nohup marimo edit app.py --host 0.0.0.0 --port 7860 --no-token > /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
log "All services active!"
log " - Memgraph: port 7687"
log " - ZeroClaw: port 7862"
log " - OmniRoute: port 20128"
log " - Graph Viewer: port 7861"
log " - Marimo UI: port 7860 (primary)"
# Keep container alive
log "Holding container open. Access the UI at https://your-space.hf.space"
wait
|