VerdantClaw-Secure / scripts /entrypoint.sh
TheEdict's picture
Start Ollama and configure Marimo AI
a6b7d4e verified
Raw
History Blame Contribute Delete
5.2 kB
#!/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