diff --git a/diagnostic/index.html b/diagnostic/index.html
index d7a576c..c79b869 100644
--- a/diagnostic/index.html
+++ b/diagnostic/index.html
@@ -2641,7 +2641,7 @@
// Liste neu aufbauen
list.innerHTML = '';
let anyLoading = false, anyError = false;
- const labels = { f5tts: 'F5-TTS', whisper: 'Whisper STT', flux: 'FLUX Image-Gen' };
+ const labels = { f5tts: 'F5-TTS', whisper: 'Whisper STT', flux: 'FLUX Image-Gen', llm: 'Lokales LLM' };
for (const [s, info] of Object.entries(_serviceState)) {
const row = document.createElement('div');
row.style.cssText = 'display:flex;align-items:center;gap:6px;';
diff --git a/xtts/llm-adapter/adapter.py b/xtts/llm-adapter/adapter.py
index 1da8fc7..db049bb 100644
--- a/xtts/llm-adapter/adapter.py
+++ b/xtts/llm-adapter/adapter.py
@@ -110,7 +110,22 @@ async def _call_llama(messages: list, *, max_tokens: int, temperature: float,
return {"ok": False, "content": "", "error": str(e)[:300]}
+# B0.5-2: Lade-Status ans Diagnostic (service_status, service="llm"). Wir kennen
+# den Download-Fortschritt nicht (llama-swap gibt ihn nicht her), aber wir melden
+# den Zustand bei Modellwechsel: loading -> ready/error. _last_model = aktuell
+# geladenes; _ready_models = in dieser Session schon einmal bereit gewesene
+# (fuer den "frisch geladen"-Hinweis 🎉 bei langem Erst-Load).
+_last_model = None
+_ready_models: set = set()
+
+
+async def _emit_llm_status(ws, state: str, model: str, **extra) -> None:
+ await _send(ws, "service_status",
+ {"service": "llm", "state": state, "model": model, **extra})
+
+
async def _handle_llm_request(ws, payload: dict) -> None:
+ global _last_model
req_id = payload.get("requestId", "")
messages = payload.get("messages") or []
if not isinstance(messages, list) or not messages:
@@ -123,11 +138,30 @@ async def _handle_llm_request(ws, payload: dict) -> None:
stop = payload.get("stop")
tools = payload.get("tools") or None
model = (payload.get("model") or "").strip() or None
+ eff_model = model or LLM_MODEL
+
+ # Modellwechsel (oder erster Request) → llama-swap laedt/swappt: Status melden.
+ switching = eff_model != _last_model
+ if switching:
+ await _emit_llm_status(ws, "loading", eff_model)
+
t0 = time.time()
res = await _call_llama(messages, max_tokens=max_tokens,
temperature=temperature, stop=stop, tools=tools,
model=model)
dt = time.time() - t0
+
+ if switching:
+ if res.get("ok"):
+ fresh = (eff_model not in _ready_models) and dt > 25
+ _ready_models.add(eff_model)
+ _last_model = eff_model
+ await _emit_llm_status(ws, "ready", eff_model,
+ loadSeconds=round(dt, 1), freshlyDownloaded=fresh)
+ else:
+ # bei Fehler _last_model NICHT setzen → naechster Versuch meldet erneut loading
+ await _emit_llm_status(ws, "error", eff_model,
+ error=(res.get("error") or "")[:120])
tc = res.get("tool_calls")
logger.info("llm_request id=%s model=%s -> ok=%s %.2fs content_len=%d tool_calls=%d",
(req_id[:8] if req_id else "?"), model or LLM_MODEL, res.get("ok"), dt,