motif64

m64_fd6b2982ea67 / start.sh

90 lines, 4.0 KBraw
1#!/usr/bin/env bash2# opencode-basalt-5090 entrypoint. Runs inside the container; takes no arguments.3# Basalt on 127.0.0.1:9000 (the model), opencode serve on 127.0.0.1:4096, ttyd on 0.0.0.0:7681,4# then the control gateway on $M64_PORT. Port 7681 is [runtime.app]: m64 exposes it on a second5# front port, where each browser tab gets opencode's terminal interface on the folder home.6# 0.0.0.0 is inside the container: only the gate can reach its internal network.7set -eu89echo '{"phase":"loading","detail":"loading the Basalt pack"}' >> "$M64_STATUS"1011# HOME is the folder opencode opens on: it holds only the user's files. opencode's DB, config12# and caches go to XDG dirs beside it, the gateway's session dirs to WORK_DIR. All are in the13# run's /scratch.14export HOME=/scratch/home15export XDG_CONFIG_HOME=/scratch/state/config XDG_CACHE_HOME=/scratch/state/cache \16  XDG_DATA_HOME=/scratch/state/data XDG_STATE_HOME=/scratch/state/state17export WORK_DIR=/scratch/work18mkdir -p "$HOME" "$XDG_CONFIG_HOME" "$XDG_CACHE_HOME" "$WORK_DIR/sessions"1920# Engine settings (the pack carries no flags; server settings are the flags below): hal5090's start_qwen38_flash_next_basalt_384k.sh.21# Past the trained 262144 tokens the RoPE is stretched with YaRN by 393216/262144 = 1.5.22cat > /scratch/basalt_config.json <<'JSON'23{24  "engine": {25    "expert-cache": "auto",26    "prefill": "auto",27    "spec": 7,28    "spec-min-p": 0.5,29    "max-context": 393216,30    "kv": "int8",31    "resident-experts": true,32    "vram-reserve-mib": 700,33    "rope-scaling": "yarn",34    "rope-scale": 1.5,35    "yarn-orig-ctx": 26214436  }37}38JSON39# Basalt's HOME is the state dir, so CUDA's kernel cache (~/.nv) stays out of the user's folder.40HOME=/scratch/state /opt/basalt/bin/basalt serve --config /scratch/basalt_config.json \41  --model /weights/basalt/Qwen3.8-FN-GSQ-RCO-IQ3_S.basalt \42  --alias qwen3.8-flash-next-iq3_s-basalt-384k \43  --vision dynamic --host 127.0.0.1 --port 9000 &44BASALT_PID=$!4546# The gateway reaps neither child, so a dead one lingers as a zombie (state Z): test the47# state, not just whether the pid exists.48alive() { [ -r "/proc/$1/stat" ] && [ "$(cut -d')' -f2 "/proc/$1/stat" | cut -d' ' -f2)" != Z ]; }4950until curl -sf --max-time 2 http://127.0.0.1:9000/health >/dev/null; do51  if ! alive "$BASALT_PID"; then52    echo '{"phase":"error","detail":"Basalt exited while loading"}' >> "$M64_STATUS"53    exit 154  fi55  sleep 256done57echo '{"phase":"loading","detail":"starting opencode"}' >> "$M64_STATUS"5859# Packages opencode installs on first start, warmed at build time (no network at run time).60cp -rn /opt/opencode-capsule/.config/. "$XDG_CONFIG_HOME/"61cp -rn /opt/opencode-capsule/.cache/. "$XDG_CACHE_HOME/"62export OPENCODE_CONFIG=/capsule/opencode.json63# Run from $HOME: it is the one project. The gateway still gives each of its sessions a64# directory under $WORK_DIR/sessions.65cd "$HOME"66# opencode names a project by its git root commit; without one the folder is just "global".67if [ ! -d .git ]; then68  git init -q -b main69  git -c user.name=capsule -c user.email=capsule@localhost commit -q --allow-empty -m home70fi71opencode serve --hostname 127.0.0.1 --port 4096 --pure &72OPENCODE_PID=$!73until curl -sf --max-time 2 http://127.0.0.1:4096/global/health >/dev/null; do74  alive "$OPENCODE_PID" || { echo '{"phase":"error","detail":"opencode exited while starting"}' >> "$M64_STATUS"; exit 1; }75  sleep 176done7778# Each browser tab runs one TUI on the shared server: sessions show up in the API too.79ttyd --writable --interface 0.0.0.0 --port 7681 -t titleFixed=opencode -t disableLeaveAlert=true \80  opencode attach http://127.0.0.1:4096 --dir "$HOME" &81TTYD_PID=$!8283# If Basalt, opencode or ttyd dies, take the container down so m64 reports the error. $$ is the84# gateway after the exec below.85( while alive "$BASALT_PID" && alive "$OPENCODE_PID" && alive "$TTYD_PID"; do sleep 5; done86  echo '{"phase":"error","detail":"Basalt, opencode or ttyd exited"}' >> "$M64_STATUS"87  kill -TERM $$ ) &8889export AGENT_PROVIDER=basalt AGENT_MODEL=qwen3.8-flash-next-iq3_s-basalt-384k90exec /opt/gateway/bin/python /capsule/agent_gateway.py