Files
ARIA-AGENT/docs/flux-imagegen-plan.md
T
duffyduck 7e53dcfed3 feat(flux): Bildgenerierung via FLUX.1-dev — flux-bridge auf Gamebox
Eigener Compose-Stack im /flux Verzeichnis (kann auf separater Maschine
laufen). aria-bridge routet flux_request via RVS, ARIA referenziert das
fertige PNG im Reply mit [FILE: ...]-Marker. Brain-Tool flux_generate
mit Caps fuer steps/dimension.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 22:33:48 +02:00

8.4 KiB

FLUX.1-dev Bildgenerierung — Architektur & Stand

Ergaenzung des ARIA-Agent-Stacks um native Text-to-Image-Generierung via FLUX.1-dev auf der Gamebox. Folgt dem gleichen Pattern wie f5tts / whisper: ein eigener Container auf dem Gaming-PC, der sich selbst per WebSocket zum RVS verbindet und auf seinen Request-Typ lauscht.

Pipeline

Stefan / App
     │ Chat-Nachricht ("mal mir einen Sonnenuntergang ueberm Hangar")
     ▼
aria-bridge ── send_to_core ──▶  aria-brain
                                       │ chooses tool: flux_generate(prompt=..., width=..., ...)
                                       │ POST /internal/flux-generate
                                       ▼
                              aria-bridge (VM)
                                       │ pushes  {type: "flux_request",
                                       │           payload: {requestId, prompt, ...}}
                                       │ via RVS-Broadcast
                                       ▼
                                    RVS
                                       │ fanout
                                       ▼
                              flux-bridge (Gamebox)
                                       │ FluxPipeline.from_pretrained(...)
                                       │ pipeline(prompt, width, height, steps, guidance).images[0]
                                       │ PIL → PNG → base64
                                       │ {type: "flux_response", payload: {state:"done",
                                       │   requestId, base64, mimeType, ...}}
                                       ▼
                                    RVS
                                       │
                                       ▼
                              aria-bridge (VM)
                                       │ _pending_flux[requestId].set_result(payload)
                                       │ base64-decode → /shared/uploads/aria_generated_<ts>.png
                                       │ HTTP 200 zurueck an Brain mit {path, sizeBytes, ...}
                                       ▼
                              aria-brain
                                       │ Tool-Result + Hint: "schreib [FILE: {path}] in deine Antwort"
                                       │ Final-Reply: "Hier dein Bild:\n[FILE: /shared/uploads/aria_generated_<ts>.png]"
                                       ▼
                              aria-bridge
                                       │ _FILE_MARKER_RE → file_from_aria-Event
                                       │ Marker bleibt im Chat-Text fuer Hist; App rendert das Bild inline
                                       ▼
                                  App + Diagnostic

Komponenten

1. flux/bridge.py (neu) — flux-bridge Container

  • FluxPipeline (diffusers) mit enable_model_cpu_offload() als Default, damit FLUX.1-dev (~24 GB on disk, ~12 B params) auf einer RTX 3060 (12 GB VRAM) ueberhaupt laeuft.
  • Lazy-Load: Modell wird beim ersten flux_request (oder im Initial-Load) geladen, service_status: "flux", state: "loading" | "ready" | "error" wird via RVS broadcastet → Diagnostic-Badge zeigt's an.
  • Single-Worker-Queue (_flux_queue) — GPU darf nicht parallel rendern, sonst OOM oder Crash.
  • Progress-Ping: flux_response {state: "rendering"} direkt nach Queue-Pickup, damit die aria-bridge weiss "Auftrag angekommen", auch wenn der eigentliche Render 60s braucht.
  • Caps:
    • width/height: 256 .. FLUX_MAX_DIM (Default 1536), gesnappt auf Vielfache von 64.
    • steps: 1 .. FLUX_MAX_STEPS (Default 50).
    • guidance_scale: 0.0 .. 20.0.
    • prompt: max 2000 chars.
  • Env-Switches:
    • FLUX_MODEL — Default black-forest-labs/FLUX.1-dev (non-commercial). Alt: FLUX.1-schnell (Apache-2.0, 4 Steps, deutlich schneller).
    • FLUX_OFFLOADmodel (default), sequential (sparsamer, langsamer) oder none (alles auf GPU; nur fuer >=24 GB VRAM-Karten).
    • FLUX_DTYPEbfloat16 (default) oder float16.
    • HF_TOKEN — FLUX.1-dev braucht HuggingFace-Login.

2. flux/docker-compose.yml — eigener Stack

Bewusst NICHT mit in xtts/docker-compose.yml gepackt: FLUX kann auch separat laufen (z.B. spaeter auf einer 4090, waehrend die 3060 weiter TTS+STT bedient). Eigener Compose, eigene .env.example, eigenes hf-cache/-Volume.

  • GPU-Reservation analog zu f5tts/whisper.
  • Volume ./hf-cache:/root/.cache/huggingface — wenn flux auf der gleichen Maschine wie xtts laeuft kann man ../xtts/hf-cache symlinken, dann ist der Modell-Cache geteilt.
  • Restart unless-stopped.

3. rvs/server.js — Allowlist erweitert

Neue Typen: flux_request, flux_response (auch wenn das Initial-Load- broadcast service_status bereits zugelassen war).

4. bridge/aria_bridge.py

  • self._pending_flux: dict[str, asyncio.Future] — request_id → future.
  • self._remote_flux_ready: bool — wird von service_status Updates gefuellt; steuert den HTTP-Timeout (240 s wenn ready, 900 s waehrend des allerersten Modell-Downloads).
  • flux_response-Handler: Progress-Ping (state == "rendering") bleibt no-op auf der Future; state == "done" setzt die Future, Error setzt {"error": ...}.
  • _flux_generate(prompt, width, height, steps, guidance, seed) — Helper:
    1. UUID + Future
    2. flux_request broadcasten
    3. asyncio.wait_for(future, timeout=...)
    4. base64 → /shared/uploads/aria_generated_<ts>.png
    5. dict mit {ok, path, sizeBytes, width, height, steps, guidance, seed, model, renderSeconds}
  • HTTP-Endpoint POST /internal/flux-generate im internen Listener (Port 8090). Validiert prompt + clamps, ruft _flux_generate, gibt Result als JSON zurueck.

5. aria-brain/agent.py — META-Tool flux_generate

{
  "name": "flux_generate",
  "parameters": {
    "prompt": "string (englischer Prompt — FLUX liefert auf EN besser)",
    "width":  "integer (256..1536, default 1024)",
    "height": "integer (256..1536, default 1024)",
    "steps":  "integer (1..50, default 28)",
    "guidance_scale": "number (default 3.5)",
    "seed":   "integer (optional)"
  }
}

Dispatcher:

  • POSTet {prompt, width, height, steps, guidance_scale, seed} an http://aria-bridge:8090/internal/flux-generate (urllib, 1200 s Timeout — der erste Render kann den 24 GB Modell-Download triggern).
  • Bei ok=true gibt das Tool den Pfad + Render-Stats zurueck und weist Claude explizit an: "Schreibe [FILE: <path>] in deine Antwort an Stefan, dann zeigt die App das Bild inline."
  • Brain ueberlegt sich den Begleittext selber und packt den Marker an passende Stelle.

6. diagnostic/index.html — Status-Badge

Label flux: 'FLUX Image-Gen' zum bestehenden updateServiceStatus()-Switch hinzugefuegt — kein neuer Code, gleicher Banner-Mechanismus wie F5-TTS / Whisper.

File-Lifecycle

Generierte Bilder leben unter /shared/uploads/aria_generated_<ts>.png (gleicher Folder wie User-Uploads). Damit:

  • [FILE: ...]-Marker funktioniert (Bridge erlaubt nur Pfade unter /shared/uploads/).
  • File-Manager-Endpoints in Diagnostic (Liste/Loeschen/Zip) sehen sie ohne Sonderbehandlung.
  • Memory-Anhaenge: ARIA kann ein generiertes Bild im selben Turn an einen Memory-Eintrag haengen (memory_save(attach_paths=[path])).

Bekannte Stolpersteine

  • HF-Login: FLUX.1-dev ist gated. Vor erstem Start HF_TOKEN im .env setzen oder im Container huggingface-cli login machen, sonst 403 beim ersten Download.
  • Erster Render dauert lang: 24 GB Modell laden + CUDA-Warmup → 5-10 min realistisch. Brain-HTTP-Timeout ist 1200 s, RVS-Future-Timeout 900 s (loading-Modus). Stefan sollte beim ersten "Mal mir was"-Request ein bisschen Geduld haben — danach sind Renders ~30-90 s.
  • Lizenz: FLUX.1-dev ist non-commercial (FLUX.1 Dev Non-Commercial License). Fuer kommerzielle Nutzung muss man auf FLUX.1-schnell (Apache-2.0) oder FLUX.1-pro (API only) wechseln. Stefan kann das ueber FLUX_MODEL in der .env umstellen.
  • VRAM: 12 GB (3060) reichen NUR mit enable_model_cpu_offload. Bei Out-of-Memory in den Logs auf FLUX_OFFLOAD=sequential switchen (deutlich langsamer, aber peak-VRAM ~6 GB).
  • Parallele Calls: Single-Worker-Queue in der flux-bridge — ein zweiter flux_generate-Tool-Call von Brain wartet, bis der erste fertig ist. In der Praxis kein Problem, weil Stefan eh nicht zwei Bilder gleichzeitig macht.