The llama-swap conflict check on the apply/create routes only ever runs
at THAT session's own launch/apply moment, and cannot see a swap caused
by a DIFFERENT session's later, ordinary use. Confirmed live: a second
Codex session picking a different model launched with no warning at
all — nothing conflicted at that exact instant — yet it silently
evicted the first session's model regardless (llama.cpp runs one model
at a time). Reproduced and root-caused via direct API calls against a
live test-picker instance rather than guessing.
- detectCustomModelSwapDisplacements() (custom-model-routes.ts): groups
live sessions with a customModel by endpointId, checks each group's
endpoint via GET /running once, and flags a session whose own modelId
is no longer in the running list. Read-only, best-effort per endpoint
like refreshAllCustomModelHosts's sibling sweep.
- Notifies once per displacement via a caller-owned de-dupe Set: a
session id is added when displaced, removed once its own model is
loaded/ready again, so a later genuinely-new displacement can notify
again.
- New periodic sweep in server.ts (CUSTOM_MODEL_SWAP_CHECK_INTERVAL_MS,
20s — much shorter than the 5-minute model-list refresh, since this
is time-sensitive) broadcasts a new custom-model:swapped-out SSE
event per displacement. De-dupe Set cleared per-session on session
cleanup to avoid an unbounded leak.
- Frontend: global toast (not tied to the displaced session's tab,
since the point is warning before the user types into it) naming the
session, its previous model, and what's currently loaded.
Chose the "detect after the fact" scope (vs. checking before every
message send, which would add a round-trip to every turn on every
custom-model session) per explicit user decision after being presented
the trade-off.
9 new tests for the detection logic (flag/clear/re-flag cycle,
unreachable/deleted endpoints, non-llama-swap servers, multiple
sessions on one endpoint). SSE registry bumped 158->159, parity test
passing. Typecheck/lint/frontend-syntax clean; full suite shows no new
regressions (9 more passing than baseline, matching the new tests;
same pre-existing Windows-environment failures).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RqZeHrRS6DYcGcGX2p9EwG