Commit Graph
357 Commits
Author SHA1 Message Date
Frank b5211845da Hermes: drop the :8090 healthcheck (messaging gateway has no HTTP endpoint)
'hermes gateway run' starts the messaging gateway (Signal SSE), not the :8090
web dashboard, so probing 8090 always reported unhealthy. The container's
running state plus the daemon's SSE connection are the real health signal.
2026-08-20 12:30:42 -07:00
Frank 5e71b0584f Hermes: run the headless gateway (not the TUI) in the container
The image's default s6 entrypoint launches the interactive TUI, which exits
without a TTY and crash-loops the container. Override the entrypoint to run
'hermes gateway run --force' (the documented Docker mode) and point HERMES_HOME
at the mounted data dir so the Signal platform config + state persist. The
Signal platform is enabled in config.yaml (platforms.signal.enabled).
2026-08-20 12:14:18 -07:00
Frank b167a07fc0 Hermes: wire the Signal adapter to the host signal-cli daemon
The hermes container reaches the host signal-cli daemon via podman's
host.containers.internal alias (127.0.0.1 in the container is not the host).
SIGNAL_ACCOUNT/SIGNAL_ALLOWED_USERS come from the git-ignored .env (the phone
number is personal, not committed). Move the data volume to a dank-owned path
(/opt is root-owned and not writable by the run user).
2026-08-20 10:51:43 -07:00
Frank bec56d2a72 ComfyUI docs: document ComfyUI-Manager custom node
ComfyUI-Manager (V3.41) is installed in the mounted custom_nodes dir and
self-installs its pip deps on start. Document the install command, the
bind-mount-shadows-image gotcha, and the /manager/version health check.
2026-08-19 17:10:26 -07:00
Frank a6b3d4a522 ComfyUI docs: reflect the running GPU (gfx1151) container
Rewrite ComfyUI.md to match reality: comfyui-rocm:gfx1151 built from
Containerfile.comfyui on AMD's gfx1151 base, device passthrough, video group
only (render is unmappable in rootless), data under /home/dank/comfyui-data,
boot-persistent via a user systemd unit. Mark research 'way 1' as applied and
update the repo-consequence section (the CPU config is no longer the default).
2026-08-19 16:16:50 -07:00
Frank bb188becb0 ComfyUI: persist models/data under /home/dank/comfyui-data
/opt is root-owned and not writable by the run user. Point the model/input/
output/custom_nodes mounts at a dank-owned path so the container can write
them without sudo. The tests do not assert volume paths, so this is a no-op
for the suite.
2026-08-19 15:55:00 -07:00
Frank 88dcd3cc0f ComfyUI: rootless-correct GPU group config (video only)
Rootless podman cannot map the 'render' gid (990) into the container
namespace (dank's subgid range is 100000+), so --group-add render fails to
start the container. GPU access actually comes from the /dev/kfd + /dev/dri
passthrough, checked host-side (the run user is already in 'render' on the
host). So add only the 'video' group (which resolves) and drop 'render'.

Update the group test to assert video present and render ABSENT (with the
rootless rationale), per the approved rootless config.
2026-08-19 15:50:28 -07:00
Frank 354ddc473f ComfyUI: GPU (gfx1151 ROCm) build via container
Replace the CPU stock image with a container built from
Containerfile.comfyui on AMD's gfx1151-tagged vLLM base — the only torch
build verified to report torch.cuda.is_available()=True on the Strix Halo
APU (Radeon 8060S, capability (11,5)).

- Containerfile bakes the ComfyUI code in and installs its deps, but skips
  the torch family (the base image already ships the gfx1151 ROCm
  torch/torchvision/torchaudio; an unpinned 'torch' in requirements.txt would
  clobber the gfx1151 kernels).
- compose comfyui service: build + image comfyui-rocm:gfx1151, passes
  /dev/kfd + /dev/dri, adds video+render groups, drops --cpu. Models/data
  persist under /opt/comfyui.
- Un-skip the four compose-wiring acceptance tests (the gate for this work).
2026-08-19 15:20:46 -07:00
Frank aa38c556b2 SearXNG docs: document the 429 root cause + pass_ip fix
The JSON rate cap (API_MAX=4/hour) is hardcoded in Python, not settable in
limiter.toml; pass_ip is the only bypass. Rootless podman strips the client IP
on published-port hits (the container sees a slirp source), so local subagents
must present a pass_ip source. Document the slirp IP-strip, the pass_ip
expansion, and the root-owned config file (one-off sudo cp to update).
2026-08-19 12:48:53 -07:00
Frank 4fa9fdf36e SearXNG: stop rate-limiting local subagents (pass_ip covers slirp/loopback)
Root cause of the 429s: the ip_limit rate limiter caps JSON (format!=html)
requests at API_MAX=4 per IP per hour, and that constant is hardcoded in
Python (searx/botdetection/ip_limit.py), not settable in limiter.toml. The
only bypass is pass_ip (filter_request returns before ip_limit runs).

Rootless podman strips the client IP on published-port hits, so the container
sees a slirp/bridge source (10.88.x/10.89.x), never the real client - hence
even a LAN-IP curl 429'd on /search. Expand pass_ip to loopback + the host's
private podman/slirp ranges (plus the existing LAN) so local subagents present
a trusted source and skip the rate limit entirely. All these ranges are
reachable only from the host or LAN, never the internet.
2026-08-19 12:29:27 -07:00
Frank 048e7eaaba frank-default-large: full 262144 context, 1 slot
User request 2026-08-19 (second pass): parallel slots degraded
performance. PARALLEL=1, CTX_SIZE=262144 (native max, -c equals the
per-slot context with one slot). Concurrent requests queue on the
single slot; the server never preempts a running generation.
pi models.json contextWindow/maxTokens back to 262144 (outside repo).
Docs updated to match.
2026-08-19 11:17:31 -07:00
Frank 8e4d63b68d frank-default-large: 200000 context per slot (400000 total, 2 slots)
User request 2026-08-19: lower per-stream context from 262144 to 200000.
CTX_SIZE is the total; llama.cpp splits it across the 2 parallel slots.
f16 KV drops from ~32 GiB to ~24 GiB, adding OOM headroom.

Docs: sync the 2026-08-18 service swap (frank-default-large on dankclaw,
frank-default-small on dankserver) across AGENTS.md, README.md,
deployment.md, ciru-activefpx-promptforge.md, and index.md. The pi
models.json contextWindow/maxTokens for frank-default-large move
262144 -> 200000 (separate file, outside the repo).
2026-08-19 10:38:53 -07:00
Frank 3d4604c19f Stand up open-webui on dankclaw (quadlet, boot-persistent)
Replace the dead dankserver open-webui (bare container, :3000, pointed at a
dead :9090 backend) with a boot-persistent quadlet on dankclaw:
- CPU image (:main); dankclaw is CPU-only, so the :cuda image is wasted.
- Isolated on slirp4netns; publishes 3005 (3000 is Gitea's HTTP port).
- Default LLM backend is the local vLLM on 52625 (frank-default-large).
- Data persists under /home/dank/Containers/open-webui/data.
- Caddy route now proxies to the published LAN port (the container is not on
  Caddy's network).

Also corrects the model/port mapping in the docs: the live state (verified
2026-08-19) is frank-default-large on vLLM :52625 (dankclaw) and
frank-default-small on llama.cpp :7770 (dankserver) — the reverse of the
2026-08-17 note.
2026-08-19 01:04:50 -07:00
Frank 9f4c0d4175 SearXNG deploy: do not systemctl enable the generated units
Quadlet units are generator-managed; systemctl enable fails on them
('transient or generated'). The [Install] WantedBy=default.target in each
.container file is itself the enablement (is-enabled reports 'generated'), and
with user linger on they start at boot. Drop the enable step; daemon-reload and
start are enough.
2026-08-19 00:05:25 -07:00
Frank 06ac2a84cf SearXNG quadlet: use AddDevice= (the generator rejects Device=)
Device= in [Container] is a [Volume]-group key; the container device key is
AddDevice= (maps to podman --device). Update the /dev/net/tun device line and
the test seam.
2026-08-19 00:00:42 -07:00
Frank e036296fd1 SearXNG quadlet: use AddCapability= (the generator rejects CapAdd=)
The podman quadlet generator fails with "unsupported key 'CapAdd' in group
'Container'" and skips the whole unit. The correct key is AddCapability=
(maps to podman --cap-add). Update the gluetun unit and its test seam.
2026-08-18 23:57:25 -07:00
Frank d7c66b0253 SearXNG deploy: do not enable the generated .network unit
The quadlet .network unit is generator-managed and cannot be enabled; it is
pulled in automatically by the containers that set Wants=/After=searxng-network.
Enable only the three container units. The explicit start of the network is kept
(start works on generated units).
2026-08-18 23:46:35 -07:00
Frank f488382b08 SearXNG docs: document quadlet boot-persistence for the trio
Update SearXNG, Gluetun, and Valkey to describe the quadlet units instead of
compose: searxng sets Network=gluetun.container, the units install to
~/.config/containers/systemd/, and scripts/deploy-searxng-quadlet.sh deploys
them. Add a Boot Persistence section to the Stack doc. Correct the Gluetun
tunnel check (the :8000 server 404s; verify tun0 instead) and note the pinned
10.89.2.0/24 subnet.
2026-08-18 23:42:45 -07:00
Frank 71fe8c008f SearXNG: move the trio out of compose into quadlet deployment
Remove gluetun/searxng/valkey from dankclaw/compose.yaml (they are now
quadlet units) so podman-compose up can no longer fight them for the netns and
port 8081. Add scripts/deploy-searxng-quadlet.sh: an idempotent installer that
copies the units to ~/.config/containers/systemd/, daemon-reloads, enables them
for boot, and starts them in dependency order. Safe to run on first migration
and on every later change.
2026-08-18 23:34:08 -07:00
Frank 6e9bfd5d3e SearXNG: define the gluetun+searxng+valkey trio as quadlet units
Converts the podman-compose SearXNG stack to boot-persistent quadlet units so
it survives a reboot (the compose deployment did not). searxng sets
Network=gluetun.container, which makes it reuse gluetun's network namespace so
outbound search traffic exits the WireGuard tunnel; it publishes no port of its
own (the port lives on gluetun). gluetun and valkey join a pinned searxng
network (10.89.2.0/24, DNS-enabled) so searxng reaches valkey by name.

Secrets stay in /opt/searxng/.env (mode 0600), referenced via [Service]
EnvironmentFile= so ${VAR} expands. Adds a bats seam asserting the netns
wiring, port placement, boot install, and that no secret material is tracked.
2026-08-18 23:20:28 -07:00
Frank aef7eefa35 Gluetun: healthcheck via the tun0 tunnel interface
The :8000 status server 404s on every path and the image has no curl, so the
prior healthchecks could not pass. Check /sys/class/net/tun0 instead: it exists
only while the WireGuard tunnel is connected, so the healthcheck reflects real
VPN state.
2026-08-18 18:12:04 -07:00
Frank 39f43d010a Gluetun: fix healthcheck (no curl in image; /health is not an endpoint)
The gluetun image ships wget, not curl, and its status server answers 200 at
/ on port 8000 (not /health). The old curl-based healthcheck always failed, so
the container read 'unhealthy' even with a working tunnel. Use wget against /.
2026-08-18 18:00:10 -07:00
Frank c390135d56 SearXNG: trusted group needs Caddy XFF; trust the podman bridge
A direct hit on the published port has no X-Forwarded-For header, so the
bot-detection cannot resolve a client and returns 429. SearXNG must be
reached through Caddy (search.dankclaw.local), which sets X-Forwarded-For.
Add the podman bridge subnets to trusted_proxies so Caddy's source is
trusted for XFF extraction; note the CIDR is dynamic and should be pinned.
Verified agentic JSON search returns 26-31 relevant results via this path.
2026-08-18 17:52:44 -07:00
Frank 9ca22d1c34 Gluetun/Valkey: use fully-qualified docker.io image names
The host has no unqualified-search registries in registries.conf, so the
short names qmcgaw/gluetun and valkey/valkey did not resolve and the pull
hung. Qualify them with docker.io/ so the pull works on any host.
2026-08-18 16:39:06 -07:00
Frank 9fd82dc6e1 Reduce CTX_CHECKPOINTS from 32 to 16 in env file to free ~16 GiB VRAM and prevent OOM crashes 2026-08-18 16:12:52 -07:00
Frank 8c391fe120 Reduce ctxcp from 32 to 16 to free ~16 GiB VRAM headroom and prevent OOM crashes during prompt processing 2026-08-18 16:11:58 -07:00
Frank a046d2c89d Gluetun: pass full single-peer WireGuard config to the container
The compose only forwarded VPN_SERVICE_PROVIDER, VPN_TYPE and the private
key, so Gluetun could not form a tunnel. Forward the peer public key,
endpoint IP/port, addresses, allowed IPs and keepalive interval. Add
matching placeholders to .env.example (current Gluetun uses the
single-peer WIREGUARD_* model, not the old WIREGUARD_PEERS_* names).
2026-08-18 15:16:50 -07:00
Frank f846b8a36e test: skip ComfyUI GPU migration tests until the ROCm build lands
The compose still runs ComfyUI with --cpu (the gfx1151 torch image is not
built yet), so the four compose-wiring ROCm tests fail. Skip them with a
pending note; the Containerfile test stays active. Re-enable when the GPU
migration is applied.
2026-08-18 13:55:37 -07:00
Frank b4f1043b1a Gitea: document rootless privileged-port sysctl fix
Rootless podman cannot bind ports below 1024 by default, so gitea-caddy
(publishes 80/443) crash-looped (13,000+ restarts). Fix: one-time sysctl
net.ipv4.ip_unprivileged_port_start=80, persisted in
/etc/sysctl.d/99-rootless-ports.conf. Applied 2026-08-18.
2026-08-18 13:55:37 -07:00
Frank e3cd2aca1b SearXNG: add limiter.toml trusted group (LAN /24), wire into deploy
The trusted group lives in limiter.toml, not settings.yml. Add
shared/searxng/limiter.toml trusting 192.168.0.0/24 in pass_ip and
trusted_proxies, copy it into /opt/searxng/config on deploy, and correct
the SearXNG doc. New test seam: tests/searxng_limiter.bats.
2026-08-18 13:55:37 -07:00
Frank e5f21a5562 AGENTS.md: document the Pi models.json location and resolution rules
Note that the Pi agent reaches the fleet via ~/.pi/agent/models.json
(outside the repo), that the model ids are stable and referenced by
settings.json, and the two resolution rules (default = provider+model pair;
subagents = unique bare id). Gives the per-slot contextWindow values.
2026-08-18 09:00:05 -07:00
Frank a08be1641f frank-default-large: full native 262144 context per slot (524288 total)
llama.cpp splits -c across -np slots; to give each of the 2 slots the full
262144 native context, set CTX_SIZE=524288. KV ~32 GiB; fits the 96 GiB
unified pool. Update env default, serve-script fallback, and the deployment
doc line.
2026-08-18 08:01:17 -07:00
Frank 819b9d448a Docs: reflect the 2026-08-18 second swap (rename + Qwen3.6 restore)
- AGENTS.md: topology table, second-swap note, benchmark policy service
  names, mark FastMTP section retired, update model-load quirk.
- docs/index.md: intro, topology diagram, active-deployment + CIRU
  reference service names.
- docs/deployment.md: overview table, manual-update paths, rewrite both
  service-unit descriptions (Dankserver=Qwen3.6 Q6_K_P frank-default-small,
  Dankclaw=CIRU frank-default-large), validation model name.
2026-08-18 01:29:21 -07:00
Frank 1ba9618fcc Swap fleet naming + restore Qwen3.6-35B-A3B Q6_K_P on Dankserver
- Restore the pre-2026-08-17 Qwen3.6-35B-A3B-Uncensored-HauhauCS-Aggressive
  Q6_K_P + ngram-mod setup as frank-default-small on Dankserver (port 7770,
  upstream llama.cpp b10121, MoE experts on CPU via --n-cpu-moe 36).
- Rename the CIRU Qwen3.8-27B ActiveFPX setup from frank-default-small to
  frank-default-large (Dankclaw, port 52625); bump to CTX_SIZE=262144
  (native max) and PARALLEL=2 (96 GiB unified pool).
- Retire the Qwen3.8-27B IQ4_XS FastMTP frank-default-large (Dankserver) to
  .AGENTTRASH.
- deploy.sh: SERVICE[dankserver]=frank-default-small,
  SERVICE[dankclaw]=frank-default-large; HEALTH_WAIT[dankserver]=600.
2026-08-18 00:32:26 -07:00
Frank fe1d834d37 docs: note 128K context and thinking on for frank-default-small 2026-08-17 23:12:32 -07:00
Frank 2e1a78aeb4 frank-default-small: 128K context and thinking on
- CTX_SIZE 65536 -> 131072 (user request). KV at 128K is 8 GiB
  (64 KiB/token f16); estimated ~43 GiB used of the 64 GiB SVM pool,
  ~21 GiB headroom.
- REASONING off -> on with REASONING_FORMAT=deepseek, so <think>
  reasoning lands in message.reasoning_content (OpenAI-compatible)
  instead of being left unparsed in content.
2026-08-17 23:11:13 -07:00
Frank 64cdfc8529 docs: reflect CIRU runtime on Dankclaw in specs and deployment pages
- Dankclaw System Specs: correct RAM to 64 GiB (61 visible), GPU
  budget to the rocm-smi 64 GiB SVM figure, and replace the vLLM
  relevance section with the CIRU ROCmFPX runtime facts. Note the
  retired vLLM venvs in .AGENTTRASH. Refresh the disk figures.
- deployment.md: update the dankclaw target row (CIRU runtime).
2026-08-17 21:14:16 -07:00
Frank 3b51b5a94a dankclaw: replace vLLM with CIRU ROCmFPX llama.cpp runtime
Retire the vLLM service (frank-default-small, port 52625) on Dankclaw
and serve jcbtc/Qwen3.8-27B-CIRU-ActiveFPX-PromptForge through the CIRU
ROCmFPX llama.cpp runtime instead.

- Build llama-server from ciru-ai/ROCmFPX tag
  qwen3.8-activefpx-promptforge-v2.3 (commit 103af8b41) against the
  private TheRock ROCm 7.15 SDK in the retired ling3-ciru venv. The
  model card requires ROCm 7.15 for the advertised Strix Halo
  performance; the system ROCm 7.2.4 selects slower kernels.
  CK pinned at fdf4bb7fcc984811cef48ce817d89aac064b984a; generated
  ck/config.h + ck/version.h copied into the CK source tree so the
  ggml-hip build can include them. LLAMA_BUILD_WEBUI=OFF (HF bucket
  llama-ui returns 404; server is consumed via the OpenAI API).
- New scripts/serve-frank-small.sh + frank-default-small.env: 64K ctx,
  one slot, f16 KV, context checkpoints, prompt cache, native depth-4
  MTP on ROCm0, PromptForge DualView sidecars (FFN + GDN), temp 0.7
  top-p 0.95, reasoning off. LD_LIBRARY_PATH puts the 7.15 SDK libs
  before any system ROCm.
- Update the systemd unit description (same service name and port).
- deploy.sh: update the dankclaw target comment.
- Docs: new docs/ciru-activefpx-promptforge.md with the build runbook;
  update docs/index.md and AGENTS.md topology.
- The vLLM venvs (vllm-venv, vllm-vk-venv) were moved to
  /home/dank/.AGENTTRASH/ on the target; the vllm-vulkan plugin and
  docs were removed from the repo in an earlier commit.
2026-08-17 21:12:35 -07:00
Frank 4941d911f2 docs: correct Dankclaw RAM figure (64 GiB, 61 GiB visible)
The box was upgraded from 32 GB to 64 GB. Two vLLM sizing pages
still stated 30 GiB physical RAM; rocm-smi reports 64 GiB and free
shows 61 GiB visible. Update the hardware tables and the ROCm
overcommit guidance to match.

Also removes the vllm-vulkan backend page, its index links, and the
frank-vk-compat plugin from the working tree. The vLLM service on
Dankclaw is being retired in favor of the CIRU llama.cpp runtime.
2026-08-17 20:34:51 -07:00
Frank 044dd49011 docs: note prefix caching enabled on frank-default-small (opt-in for hybrid; ~4x TTFT on repeated prefix) 2026-08-17 18:45:49 -07:00
Frank b854ec78ad frank-default-small: enable prefix caching (opt-in for hybrid models; big TTFT win for pi's repeated system prompt) 2026-08-17 18:25:28 -07:00
Frank 1de43f6777 docs: update sibling KB for the 2026-08-17 fleet redo (llama.cpp moved to Dankserver, vLLM on Dankclaw; OpenWebUI/Hermes backend addresses) 2026-08-17 18:10:57 -07:00
Frank 8c42771877 docs: mark retired FastFlowLM/NPU pages with the port/name handoff; tighten Dankclaw system specs runtime row 2026-08-17 18:10:57 -07:00
Frank 115b0af8dc docs: reflect the 2026-08-17 evening changes (Quark model swap, tool calling, batch 8192) 2026-08-17 18:01:02 -07:00
Frank 1cebbf47f6 frank-default-small: swap to nameistoken Quark W8A8 INT8, batch 8192
- Model: nameistoken/Qwen3.6-35B-A3B-Quark-W8A8-INT8 (AMD Quark W8A8,
  vLLM-native expert layout). The Avesed quant emitted malformed Qwen3
  XML tool calls; the Quark model follows the format cleanly.
- max-num-batched-tokens lowered 16384 -> 8192 (user request).
- Chat template: neutral path qwen36-chat_template-tools.jinja (same
  base template; adds a concrete worked tool-call example).
2026-08-17 17:49:27 -07:00
Frank a17e638a1f frank-default-small: stronger tool template with a concrete worked example
The Avesed template only shows a generic format; the Qwen3.5-MoE
model kept emitting <function=get_weather(city=...)> (args baked into
the name). Add a WORKED EXAMPLE block derived from the actual tool
schema (name + parameter keys) to the system prompt.
2026-08-17 17:38:00 -07:00
Frank 20108e5b7a frank-default-small: use the repo chat_template.jinja so tools render in Qwen3 XML
The Avesed tokenizer_config.json ships no chat_template, so vLLM used its
built-in template, which does not render the <tool_call> instructions;
the model then emitted malformed XML (arguments baked into the function
name) and the qwen3_xml parser could not extract clean calls.
2026-08-17 17:13:35 -07:00
Frank 5108af11aa frank-default-small: enable tool calling (--enable-auto-tool-choice --tool-call-parser qwen3_xml)
Clients send tool_choice=auto; without these flags vLLM rejects with
HTTP 400. The Avesed chat template renders the Qwen3 XML tool format,
so qwen3_xml is the matching parser.
2026-08-17 16:50:23 -07:00
Frank c81933ccb4 OpenWebUI: retarget to Dankserver llama.cpp (:7770 moved in 2026-08-17 redo) 2026-08-17 16:39:30 -07:00
Frank 57264f7faa record performance fixes: FA_ALL_QUANTS build flag (dankserver), RDNA triton FA env (dankclaw)
- frank-default-large: GGML_CUDA_FA_ALL_QUANTS=ON is mandatory in the
  FastMTP build; without it q8_0 KV + FA falls back to a slow path and
  prefill collapses ~12x (95 -> 1312 t/s at 8K, measured)
- frank-default-small: FLASH_ATTENTION_TRITON_AMD_ENABLE=TRUE + pure-python
  flash_attn (triton_amd) + stub; without it the vision encoder warmup
  OOMs via torch SDPA
2026-08-17 16:30:22 -07:00