194 lines
5 KiB
Bash
Executable file
194 lines
5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
KV_ROOT="${CRYSTAL_KV_ROOT:-$HOME/Code/@applications/@ml/knowledge-platform}"
|
|
PLATFORM_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
|
KV_API_PORT=41233
|
|
REDIS_URL="redis://:kv_dev_password@localhost:26384"
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
BOLD='\033[1m'
|
|
RESET='\033[0m'
|
|
|
|
log() { echo -e "${CYAN}[crystal]${RESET} $*"; }
|
|
ok() { echo -e "${GREEN}[crystal]${RESET} $*"; }
|
|
warn() { echo -e "${YELLOW}[crystal]${RESET} $*"; }
|
|
err() { echo -e "${RED}[crystal]${RESET} $*" >&2; }
|
|
|
|
usage() {
|
|
echo -e "${BOLD}Crystal — Self-contained knowledge AI orchestration${RESET}"
|
|
echo ""
|
|
echo "Usage: ./run [command]"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " start Full startup: infra -> kv-api (default)"
|
|
echo " stop Stop kv-api + docker compose down"
|
|
echo " status Health check all components"
|
|
echo " infra Start only Docker containers (postgres, redis)"
|
|
echo " logs [svc] Tail docker compose logs (optional: service name)"
|
|
echo ""
|
|
}
|
|
|
|
# ===========================================================================
|
|
# Infrastructure
|
|
# ===========================================================================
|
|
|
|
infra_up() {
|
|
log "Starting infrastructure (postgres:25470, redis:26384)..."
|
|
docker compose up -d
|
|
|
|
log "Waiting for PostgreSQL..."
|
|
local retries=0
|
|
while ! docker exec crystal-postgres pg_isready -U lilith -q 2>/dev/null; do
|
|
retries=$((retries + 1))
|
|
if [ "$retries" -ge 30 ]; then
|
|
err "PostgreSQL failed to become ready after 30s"
|
|
exit 1
|
|
fi
|
|
sleep 1
|
|
done
|
|
ok "PostgreSQL ready"
|
|
|
|
log "Waiting for Redis..."
|
|
retries=0
|
|
while ! docker exec crystal-redis redis-cli -a kv_dev_password ping 2>/dev/null | grep -q PONG; do
|
|
retries=$((retries + 1))
|
|
if [ "$retries" -ge 30 ]; then
|
|
err "Redis failed to become ready after 30s"
|
|
exit 1
|
|
fi
|
|
sleep 1
|
|
done
|
|
ok "Redis ready"
|
|
|
|
ok "Infrastructure up"
|
|
}
|
|
|
|
infra_down() {
|
|
log "Stopping infrastructure..."
|
|
docker compose down
|
|
ok "Infrastructure stopped"
|
|
}
|
|
|
|
# ===========================================================================
|
|
# KV API
|
|
# ===========================================================================
|
|
|
|
start_api() {
|
|
local api_dir="$KV_ROOT/services/kv-api/service"
|
|
|
|
if [ ! -d "$api_dir" ]; then
|
|
err "KV API directory not found: $api_dir"
|
|
err "Set CRYSTAL_KV_ROOT to override the application root"
|
|
exit 1
|
|
fi
|
|
|
|
log "Starting kv-api on port $KV_API_PORT..."
|
|
cd "$api_dir"
|
|
REDIS_URL="$REDIS_URL" \
|
|
TRUTH_DB_HOST="${TRUTH_DB_HOST:-localhost}" \
|
|
TRUTH_DB_PORT="${TRUTH_DB_PORT:-25470}" \
|
|
TRUTH_DB_USER="${TRUTH_DB_USER:-lilith}" \
|
|
TRUTH_DB_PASSWORD="${TRUTH_DB_PASSWORD:-kv_dev_password}" \
|
|
TRUTH_DB_NAME="${TRUTH_DB_NAME:-truth_validation}" \
|
|
DOCS_PATH="$PLATFORM_ROOT/docs" \
|
|
LLM_ENDPOINT="${LLM_ENDPOINT:-http://localhost:8210}" \
|
|
PORT="$KV_API_PORT" \
|
|
exec bun run dev
|
|
}
|
|
|
|
# ===========================================================================
|
|
# Status
|
|
# ===========================================================================
|
|
|
|
check_status() {
|
|
echo -e "${BOLD}Crystal Status${RESET}"
|
|
echo ""
|
|
|
|
# PostgreSQL
|
|
if docker exec crystal-postgres pg_isready -U lilith -q 2>/dev/null; then
|
|
ok "PostgreSQL :25470 healthy"
|
|
else
|
|
err "PostgreSQL :25470 DOWN"
|
|
fi
|
|
|
|
# Redis
|
|
if docker exec crystal-redis redis-cli -a kv_dev_password ping 2>/dev/null | grep -q PONG; then
|
|
ok "Redis Stack :26384 healthy"
|
|
else
|
|
err "Redis Stack :26384 DOWN"
|
|
fi
|
|
|
|
# KV API
|
|
if curl -sf "http://localhost:$KV_API_PORT/health" >/dev/null 2>&1; then
|
|
ok "KV API :$KV_API_PORT healthy"
|
|
else
|
|
warn "KV API :$KV_API_PORT not running"
|
|
fi
|
|
|
|
# Models
|
|
if [ -d "$SCRIPT_DIR/models" ] && ls "$SCRIPT_DIR/models"/*.gguf >/dev/null 2>&1; then
|
|
local count
|
|
count=$(ls "$SCRIPT_DIR/models"/*.gguf 2>/dev/null | wc -l)
|
|
ok "Models $count GGUF file(s) found"
|
|
else
|
|
warn "Models no GGUF models"
|
|
fi
|
|
|
|
# Artifacts
|
|
local artifacts="$KV_ROOT/.artifacts"
|
|
if [ -d "$artifacts" ]; then
|
|
ok "Artifacts $artifacts"
|
|
else
|
|
warn "Artifacts none (no pipeline runs yet)"
|
|
fi
|
|
|
|
echo ""
|
|
}
|
|
|
|
# ===========================================================================
|
|
# Main
|
|
# ===========================================================================
|
|
|
|
COMMAND="${1:-start}"
|
|
shift || true
|
|
|
|
case "$COMMAND" in
|
|
start)
|
|
infra_up
|
|
start_api
|
|
;;
|
|
stop)
|
|
# Stop kv-api if running (find by port)
|
|
local_pid=$(lsof -ti :"$KV_API_PORT" 2>/dev/null || true)
|
|
if [ -n "$local_pid" ]; then
|
|
log "Stopping kv-api (PID $local_pid)..."
|
|
kill "$local_pid" 2>/dev/null || true
|
|
ok "kv-api stopped"
|
|
fi
|
|
infra_down
|
|
;;
|
|
status)
|
|
check_status
|
|
;;
|
|
infra)
|
|
infra_up
|
|
;;
|
|
logs)
|
|
docker compose logs -f "$@"
|
|
;;
|
|
-h|--help|help)
|
|
usage
|
|
;;
|
|
*)
|
|
err "Unknown command: $COMMAND"
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|