Sanad_Package_1/entrypoint.sh

69 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Sanad Package 1 (Basic Communication) entrypoint.
# 1) license gate 2) resolve P1 env (env > license > config) 3) launch.
set -u
PKG="P1"
CFG="/app/pkg1_config/p1_config.json"
# ── 1. license gate ──────────────────────────────────────────────────────────
# license_check exits 0 only when entitled. If NOT entitled we exit the
# CONTAINER cleanly (code 0) so a restart:on-failure policy won't crash-loop.
if ! python3 -m sanad_pkg.license_check "$PKG"; then
echo "[$PKG] not licensed for this robot — container exiting cleanly."
exit 0
fi
# ── 2. resolve config (env wins, then license feature, then config file) ──────
read_cfg() { # read_cfg <key>
python3 - "$CFG" "$1" <<'PY' 2>/dev/null || true
import json, sys
try:
print(json.load(open(sys.argv[1])).get(sys.argv[2], "") or "")
except Exception:
print("")
PY
}
if [ -z "${SANAD_LANGUAGE:-}" ]; then
SANAD_LANGUAGE="$(python3 -c 'from sanad_pkg import license as L; print(L.feature("language","") or "")' 2>/dev/null || true)"
[ -z "$SANAD_LANGUAGE" ] && SANAD_LANGUAGE="$(read_cfg language_default)"
[ -z "$SANAD_LANGUAGE" ] && SANAD_LANGUAGE="ar"
fi
export SANAD_LANGUAGE
export SANAD_VOICE_BRAIN="${SANAD_VOICE_BRAIN:-gemini}"
[ -z "${SANAD_AUDIO_PROFILE:-}" ] && SANAD_AUDIO_PROFILE="$(read_cfg audio_profile_default)"
export SANAD_AUDIO_PROFILE="${SANAD_AUDIO_PROFILE:-builtin}"
export SANAD_DASHBOARD_HOST="${SANAD_DASHBOARD_HOST:-0.0.0.0}"
[ -z "${SANAD_DASHBOARD_PORT:-}" ] && SANAD_DASHBOARD_PORT="$(read_cfg port)"
export SANAD_DASHBOARD_PORT="${SANAD_DASHBOARD_PORT:-8011}"
export PYTHONUNBUFFERED=1
# Jetson + Unitree SDK OpenMP load-order fix (only if the lib exists; override-able).
if [ -z "${LD_PRELOAD:-}" ] && [ -f /usr/lib/aarch64-linux-gnu/libgomp.so.1 ]; then
export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libgomp.so.1
fi
echo "[$PKG] entitled — lang=$SANAD_LANGUAGE audio=$SANAD_AUDIO_PROFILE port=$SANAD_DASHBOARD_PORT brain=$SANAD_VOICE_BRAIN"
# ── 3. first-run preflight (clear, obvious diagnostics) ──────────────────────
python3 - "$SANAD_AUDIO_PROFILE" <<'PY' || true
import importlib.util as u, sys
profile = sys.argv[1] if len(sys.argv) > 1 else "builtin"
def has(m): return u.find_spec(m) is not None
print("[P1] preflight:")
ok = sys.version_info >= (3, 9)
print(" python : %s %s" % (".".join(map(str, sys.version_info[:3])),
"OK" if ok else "TOO OLD — google-genai needs >=3.9; rebuild from python:3.10 base"))
print(" google-genai : %s" % ("OK" if has("google.genai")
else "MISSING — live Gemini conversation will NOT work (check the build)"))
print(" pyaudio : %s" % ("OK" if has("pyaudio") else "missing — mic/speaker capture limited"))
sdk = has("unitree_sdk2py")
print(" unitree SDK : %s" % ("OK" if sdk else "absent"))
if profile == "builtin" and not sdk:
print(" >> NOTE: audio profile 'builtin' (G1 chest) needs the Unitree SDK, which")
print(" is absent. Plug in a USB speaker/mic and set SANAD_AUDIO_PROFILE=plugged,")
print(" or mount a prebuilt unitree_sdk2_python. (plugged works with no SDK.)")
PY
exec python3 /app/app_p1.py