Dankclaw's endpoints are re-split. frank-large is the halogen-flash-server quadlet again -- the 2026-09-13 unit file was never touched by the two-day ik_llama.cpp interlude, so the runtime was still in the repo and its image is still in local storage -- retuned to the shape asked for: HALOGEN_CTX 200192 with a 400,384-position pool and two slots, exactly two 200k conversations. frank-small is new: mainline llama.cpp on the RTX 3090 serving ISTA-DASLab/Qwen3.8-27B-GSQ-RCO-GGUF at IQ3_S, using the -mtp build (it carries blk.64.nextn.*, which is what lets --spec-type draft-mtp run on the main model's own weights instead of a second 12 GiB copy) plus the BF16 vision projector, as one 131,072-token slot with f16 KV on port 7771. The host is shared now, and that is what the halogen retune pays for: HALOGEN_MAX_TOK 24576 (arena 20.6 -> 16.4 GiB, ~4-5% prefill) and the vision tower dropped (1.97 GiB) hand ~6 GiB back to the host, and the reserve rises to 20 to keep the fit check honest. Vision moved wholesale to frank-small. Retired to scripts/.AGENTTRASH/: the ik trio (env, service, serve script), the Qwen-Sharp template only that runtime read, and four benchmark harnesses bound to retired runtimes. Because retiring a file makes any test that greps it pass by absence, the seams assert the archive exists AND the live path does not.
105 lines
4.9 KiB
Bash
Executable File
105 lines
4.9 KiB
Bash
Executable File
#!/usr/bin/env bats
|
|
# Seam: the frank-large halogen-flash-server quadlet on dankclaw.
|
|
# halogen-flash-server replaced ik_llama.cpp again on 2026-09-16, so this
|
|
# service is once more a rootless Quadlet container on the gfx1151 iGPU. This
|
|
# seam pins what a flag list cannot show: the boot-persistent podman posture
|
|
# (both device nodes, memlock, the create-time image contract), the
|
|
# matched ctx/pool/slots set that IS the two-conversation promise, the
|
|
# co-tenancy budget the arena and reserve are chosen for, the image handoff to
|
|
# frank-small, and a deploy handler that retires the previous ROOT unit without
|
|
# deleting it.
|
|
|
|
load helpers
|
|
|
|
QUADLET="$REPO_ROOT/dankclaw/frank-large/quadlet/frank-large.container"
|
|
REMOTE_DEPLOY="$REPO_ROOT/scripts/deploy-remote.sh"
|
|
|
|
@test "the frank-large quadlet exists where the deployer installs it from" {
|
|
[ -f "$QUADLET" ]
|
|
}
|
|
|
|
@test "frank-large is boot-persistent, self-healing and container-shaped" {
|
|
grep -q '^WantedBy=default.target$' "$QUADLET"
|
|
grep -q '^Restart=on-failure$' "$QUADLET"
|
|
grep -q '^RestartSec=' "$QUADLET"
|
|
grep -q '^Pull=never$' "$QUADLET"
|
|
# The localhost/-aliased tag is what create-time resolution needs on this
|
|
# host; the deployer pulls the ghcr.io ref and re-tags it.
|
|
grep -q '^Image=localhost/peonist-ai/halogen-flash-server:' "$QUADLET"
|
|
}
|
|
|
|
@test "frank-large has the gfx1151 devices and the image's documented posture" {
|
|
grep -q '^AddDevice=/dev/kfd$' "$QUADLET"
|
|
grep -q '^AddDevice=/dev/dri$' "$QUADLET"
|
|
grep -q '^PodmanArgs=--ipc=host --security-opt seccomp=unconfined$' "$QUADLET"
|
|
grep -q '^Ulimit=memlock=-1:-1$' "$QUADLET"
|
|
# The weights mount must stay read-write: the first start downloads into it.
|
|
grep -q '^Volume=/home/dank/models/halogen:/models$' "$QUADLET"
|
|
}
|
|
|
|
@test "frank-large keeps the fleet alias and publishes only the API port" {
|
|
grep -q '^Environment=HALOGEN_MODEL_ID=frank-large$' "$QUADLET"
|
|
grep -q '^PublishPort=7770:8731$' "$QUADLET"
|
|
# The engine's own listener stays inside the container: it is unauthenticated.
|
|
! grep -q 'PublishPort=.*8730' "$QUADLET"
|
|
}
|
|
|
|
@test "the KV pool is exactly two conversations of the per-request ceiling" {
|
|
local ctx pool slots
|
|
ctx="$(sed -nE 's/^Environment=HALOGEN_CTX=([0-9]+)$/\1/p' "$QUADLET")"
|
|
pool="$(sed -nE 's/^Environment=HALOGEN_KV_POOL_POSITIONS=([0-9]+)$/\1/p' "$QUADLET")"
|
|
slots="$(sed -nE 's/^Environment=HALOGEN_KV_SLOTS=([0-9]+)$/\1/p' "$QUADLET")"
|
|
[ -n "$ctx" ] && [ -n "$pool" ] && [ -n "$slots" ]
|
|
# The deployed promise is two resident conversations: the pool is twice the
|
|
# ceiling, one slot per conversation. Slots still oversubscribe the pool for
|
|
# any real request, because admission reserves prompt + max_tokens.
|
|
[ "$pool" -eq $((ctx * 2)) ]
|
|
[ "$slots" -eq 2 ]
|
|
}
|
|
|
|
@test "the prefill arena stays inside the range the vendor tested" {
|
|
local max_tok reserve
|
|
max_tok="$(sed -nE 's/^Environment=HALOGEN_MAX_TOK=([0-9]+)$/\1/p' "$QUADLET")"
|
|
reserve="$(sed -nE 's/^Environment=HALOGEN_HOST_RESERVE_GIB=([0-9]+)$/\1/p' "$QUADLET")"
|
|
[ -n "$max_tok" ] && [ -n "$reserve" ]
|
|
# 32768 is the vendor default; 65536 cannot boot on this host because the
|
|
# arena alone outgrows the device budget. The arena is a per-call prefill
|
|
# chunk, so a smaller value costs prefill speed, not context.
|
|
[ "$max_tok" -le 32768 ]
|
|
[ "$max_tok" -ge 16384 ]
|
|
[ "$reserve" -ge 15 ]
|
|
}
|
|
|
|
@test "frank-large loads no vision tower: the fleet's image path is frank-small" {
|
|
! grep -q 'HALOGEN_VISION_TOWER' "$QUADLET"
|
|
grep -q -- '--mmproj' "$REPO_ROOT/scripts/serve-frank-small.sh"
|
|
}
|
|
|
|
@test "the deploy handler retires the previous ROOT unit without deleting it" {
|
|
grep -q 'retire_root_llm_large' "$REMOTE_DEPLOY"
|
|
grep -q 'systemctl stop frank-large.service' "$REMOTE_DEPLOY"
|
|
grep -q 'systemctl disable frank-large.service' "$REMOTE_DEPLOY"
|
|
grep -q 'HOME/.AGENTTRASH' "$REMOTE_DEPLOY"
|
|
! grep -qE '(^|[^[:alnum:]_])rm (-[a-zA-Z]+ )?.*frank-large' "$REMOTE_DEPLOY"
|
|
}
|
|
|
|
@test "the deploy handler installs the quadlet and gates the first start on weights" {
|
|
grep -q 'install_quadlet frank-large dankclaw/frank-large/quadlet frank-large' "$REMOTE_DEPLOY"
|
|
grep -q 'wait_for_llm_large_ready' "$REMOTE_DEPLOY"
|
|
grep -q 'qwen38-flash-next-w4b.hgn' "$REMOTE_DEPLOY"
|
|
grep -q '127.0.0.1:7770/health' "$REMOTE_DEPLOY"
|
|
}
|
|
|
|
@test "the ik_llama.cpp runtime that held this service is archived, not live" {
|
|
# Its files must not sit in scripts/ where a stale root unit could still be
|
|
# pointed at them, and must not be gone either: .AGENTTRASH is the rollback.
|
|
local retired
|
|
for retired in frank-large.env.ik-llama.cpp frank-large.service.ik-llama.cpp \
|
|
serve-frank-large.sh.ik-llama.cpp; do
|
|
[ -f "$REPO_ROOT/scripts/.AGENTTRASH/$retired" ]
|
|
done
|
|
[ ! -e "$REPO_ROOT/scripts/frank-large.env" ]
|
|
[ ! -e "$REPO_ROOT/scripts/frank-large.service" ]
|
|
[ ! -e "$REPO_ROOT/scripts/serve-frank-large.sh" ]
|
|
}
|