--- name: fleet-served-model-id-rename description: "Rename the served model id (alias) on a dank-fleet LLM endpoint and re-key every consumer that keys on it, with live verification." --- # Fleet served-model-id rename (wire rename) Renames the id an endpoint announces on the wire. The service, unit, script and env FILE names keep the old name (container/unit identity is stable) — only the served alias moves. Done this way on 2026-10-09: frank-primary→frank-archon, frank-large→frank-dragoon, frank-secondary→frank-zealot. ## 1. The knob, per engine | Endpoint | Knob | |---|---| | frank-primary (radiance, dankserver :7770) | `FRANK_PRIMARY_SERVED_NAME` in `scripts/frank-primary.env` → `--served-model-name` | | frank-large (halogen flash-server, dankclaw :7770) | `HALOGEN_MODEL_ID` in `scripts/frank-large.env` | | frank-secondary (llama.cpp, dankclaw :7771) | `ALIAS` in `scripts/frank-secondary.env` → `--alias` | Also flip the serve-script defaults (`: "${ALIAS:=…}"`, the `:?` gate messages). `scripts/deploy-remote.sh` has no alias references — the deployer needs no edit. ## 2. Consumers that key on the id (all in ONE change) - Seams: `tests/frank_{secondary,large,primary}_unit.bats` — fixture env value, the argv assertion (`--alias`), the env grep pin, the `-e HALOGEN_MODEL_ID=` render assertion. - OpenWebUI (Dankclaw, rootless quadlet, `webui.db`): `model.id`+`name`, `access_grant.resource_id` (`resource_type='model'`), `openai.api_configs` per-backend `model_ids`. Backup first (`webui.db.bak-YYYYMMDD`; the DB is WAL-mode). No sqlite3 binary in the image → `podman exec -i open-webui python3 -` with a script on stdin. Then `systemctl --user restart open-webui.service`. A stale id fails SILENTLY: OpenWebUI intersects the backend `/v1/models` with `model_ids`, so the picker just goes empty. - Hermes (`/home/dank/Containers/hermes/data/config.yaml`, root-owned → sudo): `model.default`, the provider `models:` key, every `auxiliary:` route naming the endpoint. Backup, surgical `sudo sed -i`, sweep `grep -rln ` over the data dir (session JSONs are historical — leave), restart `hermes.service hermes-webui.service` (user units). - Dev harnesses: `"model": "frank-…"` literals in `scripts/bench-*.py`, `deep-probe.py`, `calib-push.py`, `fleet-probes-swift15.sh`, `autoresearch*`. - Docs: `shared/homepage/docs.html` (headings, api-id annotations, the curl/opencode/Pi examples), endpoint runbooks, `AGENTS.md` Model Config, `serverAppConfigs-docs/Agent/OMP Harness.md`, `Dankclaw/OpenWebUI.md`. - Harness side (`~/.omp/agent/models.yml` on the dev box) — ids and `modelRoles` must name the same string; two ports on one host = two providers. ## 3. Deploy + verify `./scripts/deploy.sh --service ` per endpoint; keep the tree clean (untracked scratch files inside the repo fail the whole-tree gate — put probes in /tmp with a `node_modules` symlink to `tests/e2e/node_modules`). Verify on `/v1/models`, NEVER on a chat echo: radiance echoes the REQUESTED model name (a 200 proves nothing), llama.cpp and halogen ignore the requested id. ```bash for u in 192.168.0.235:7770 192.168.0.143:7770 192.168.0.143:7771; do curl -fsS "http://$u/v1/models"; done ``` OpenWebUI acceptance = a real browser as a family account: the welcome screen names the model and `POST /api/v1/chat/completions {"model":""}` answers. `GET /api/v1/models/list` returning `{"items":[],"total":0}` for that same account is a probe artifact, not a failure. Playwright notes: `locator.isVisible({timeout})` does NOT wait (returns immediately) — use `waitFor({state:'visible'})`; the composer is a contenteditable div, not a textarea; stable anchors are `getByRole('button', {name: /selected model/i})` and "How can I help you today?". ## 4. Trap: green deploy, old config `deploy.sh` plans from repo paths and gates on the port. A systemd drop-in under `/etc/systemd/system/.service.d/` can override `Environment=FRANK_*_ENV_FILE` and `ExecStart` to a staging worktree, so the deploy restarts a DIFFERENT tree and reports healthy (this bit frank-primary for a day after a quantization campaign). After an LLM deploy, prove the running shape: ```bash systemctl cat # drop-ins print at the bottom podman inspect --format '{{json .Config.Cmd}}' | tr , '\n' ``` Before retiring such a drop-in: diff staging vs checkout for serve script/unit/env, and `git merge-base --is-ancestor HEAD` so no campaign tuning is lost. Move it to `~/.AGENTTRASH/YYYYMMDD-topic/` (never `rm`), `daemon-reload`, restart, re-read `/v1/models`.