# Local-LLM-Adapter (Gamebox) — Plan B, Phase B0

Bringt ein lokales, schnelles LLM (Qwen3 8B) auf die Gamebox und haengt es
per RVS an ARIA — fuer die einfachen ~80 % der Turns (<1 s), waehrend Claude
das Tiefen-Hirn bleibt. Siehe `docs/plan-local-llm-router.md` im Repo-Root.

## Zwei Container (in `xtts/docker-compose.yml`)

- **`llama`** — `llama.cpp`-Server (CUDA), serviert das GGUF OpenAI-kompatibel
  auf `:8081`, nur im Compose-Netz.
- **`llm-adapter`** — verbindet sich per Token an den RVS (wie f5tts/whisper),
  nimmt `llm_request` entgegen, ruft `llama` lokal, antwortet `llm_response`.

## Modell — Auto-Download (nichts manuell ablegen)

`llama.cpp` zieht das GGUF beim **ersten Start selbst von Hugging Face** und
cached es unter `xtts/models/` (Bind-Mount → kein Re-Download bei Restart).
Default: **Qwen3 8B, Q4_K_M** aus dem offiziellen Repo `Qwen/Qwen3-8B-GGUF`.

Modell/Quant wechseln = in der `.env` der Gamebox setzen (kein Code):

```
LLM_HF_REPO=Qwen/Qwen3-8B-GGUF     # HF-Repo
LLM_HF_QUANT=Q4_K_M                # Quant-Tag (Q4_K_M, Q5_K_M, Q8_0, …)
LLM_CTX=8192                       # Kontextfenster (kleiner = weniger VRAM)
```

Mistral statt Qwen testen (A/B): `LLM_HF_REPO` auf ein Mistral-Small-3-GGUF-Repo
umstellen + Container neu — Ein-Zeilen-Wechsel, kein Code.

> Der erste Start lädt mehrere GB — Log zeigt den Download-Fortschritt.
> Danach liegt das GGUF im Cache und der Start ist sofort.

**Modell-Auswahl in ARIA Diagnostic** (on-demand laden/aktivieren mehrerer
Modelle) ist ein geplanter Folge-Baustein via `llama-swap` — siehe
`docs/plan-local-llm-router.md`.

## Start (auf der Gamebox)

```bash
cd xtts
docker compose up -d --build llama llm-adapter
docker logs -f aria-llm-adapter     # "RVS verbunden — llm-adapter online"
```

## Standalone-Test (ohne ARIA), direkt gegen llama.cpp

```bash
curl http://localhost:8081/v1/chat/completions -H "Content-Type: application/json" -d '{
  "messages":[{"role":"system","content":"Du bist ARIA."},
              {"role":"user","content":"sag kurz hallo"}],
  "max_tokens":64
}'
```

## VRAM-Hinweis (RTX 3060, 12 GB)

whisper-small (~1–2) + f5tts (~1–2) + qwen3-8b-q4 (~6) ≈ 9–10 GB. Passt, aber
knapp. Bei OOM: `LLM_CTX` reduzieren, `-ngl` senken (weniger Layer auf GPU),
oder kleineres Quant (Q4_K_S / IQ4_XS).

## Nachrichten-Kontrakt (RVS)

- `llm_request`  → `{ requestId, messages:[{role,content}], max_tokens?, temperature?, stop? }`
- `llm_response` ← `{ requestId, ok, content, error?, model, elapsedMs }`
- `llm_partial`  — reserviert fuer B2 (Token-Streaming), noch ungenutzt.
