hermes-erkenntnisse/2026-07-23-ticket32-orchestrator-charaktere.md

5.8 KiB

#32 — Video-Tool end-to-end: Orchestrator kennt echte Charaktere

Datum: 2026-07-23, VM302, Worker fuer Ticket #32

Ziel

Orchestrator (B:\barby\orchestrator\main.py, Port 8197) soll die real vorhandene Charakter-Bibliothek introspektieren (GET /api/characters) UND das charakter-Feld im /api/orchestrate-Payload auswerten, damit das Portal (cp.go-ki.eu, VM201) sich selbst introspektiert statt auf ein statisches Fallback-Manifest zurueckzufallen.

Umgesetzt (additiv, main.py.bak_20260723_*_charfeature als Backup)

1. GET /api/characters (neu)

Scannt LIVE bei jedem Aufruf B:\barby\characters-library\characters\*\character.json (kanonische Quelle, siehe _index.json.authority_note -- NICHT der Cache _index.json selbst). Pro Charakter: slug, display_name, consistency_method, completeness (ready/partial/broken, live abgeleitet -- lora_on_disk-Check bzw. refs_count-Check, nicht aus dem Manifest-Feld status uebernommen), refs_count, lora-Metadaten, identity_tokens, recommended_checkpoints, outfits, seed_canonical.

Beleg (curl, Produktion Port 8197):

GET http://127.0.0.1:8197/api/characters
-> {"source":"orchestrator_live_scan","count":5,
    "characters":[barby(ready,lora), businessman(partial,ipadapter_ref),
                  nerd(partial), passant(partial), reporter(partial)]}

2. charakter-Feld im /api/orchestrate-Payload wird ausgewertet

_orchestrate_handler liest body.get("charakter") (Alias: character), loest per get_character(slug) das volle character.json auf, mapped "christina"/"chrfischer" auf den internen slug barby (siehe public_identity_note). Unbekannter Slug -> Fallback auf barby MIT Hinweis im plan (plan.charakter.hinweis). Ergebnis landet in job.plan["charakter"] (slug, display_name, consistency_method) UND wird an run_video_job(..., character=charakter_data) durchgereicht.

run_video_job nutzt die Charakterdaten fuer das Identitaets-Lock-Startbild:

  • consistency_method == "lora" + LoRA-Datei existiert auf Platte -> LoraLoader mit lora_name/recommended_strength aus character.json, LoRA-Trigger-Wort ("chrfischer woman" bei Barby, sonst optionales lora_trigger-Feld).
  • sonst (z.B. nerd/businessman/reporter/passant, aktuell ipadapter_ref ohne Refs) -> nur identity_tokens aus character.json in den Prompt, KEINE LoRA. Zusaetzlich Hinweis in job.plan["hinweise"]: "[BÄR] Fuer volle Konsistenz noch Bootstrap/ Referenzbilder oder LoRA-Training noetig." (ehrlich, kein Fake-Beleg).
  • Checkpoint kommt aus character.json.recommended_checkpoints[0].
  • Default (kein charakter-Feld gesendet) = weiterhin exakt Barby/Christina wie vorher (identisches Verhalten, additiv -- bestehende Aufrufer brechen nicht).

Gleiche Logik zusaetzlich additiv in POST /generate (GenerateRequest.charakter, optional, Default None -> Barby wie bisher).

Beleg (curl gegen Testinstanz Port 8198, danach ComfyUI-Queue live geprueft):

POST /api/orchestrate {"prompt":"ein Mann sitzt am Schreibtisch","charakter":"nerd",...}
-> plan.charakter = {"slug":"nerd","display_name":"Nerd","consistency_method":"ipadapter_ref"}
-> job.plan.hinweise = ["Charakter 'nerd' nutzt consistency_method='ipadapter_ref' ohne
   einsatzbereite LoRA (refs_count=0) ... [BÄR] Fuer volle Konsistenz noch Bootstrap/
   Referenzbilder oder LoRA-Training noetig."]
-> LIVE in ComfyUI-Queue geprueft (GET /queue): running-Workflow hatte
   CheckpointLoaderSimple.ckpt_name = "lustifySDXLNSFW_v20-inpainting.safetensors"
   (= nerd.recommended_checkpoints[0]) UND CLIPTextEncode-Text begann mit
   "young man, tousled brown hair, black-rimmed glasses, slim build, friendly
   awkward smile, ..." (= nerd.identity_tokens) -> Charakter-Feld steuert die
   Pipeline WIRKLICH, nicht nur durchgereicht.
Unbekannter Slug "quatschname" -> Fallback korrekt auf barby, mit Hinweis-Text.

3. Deploy

  • Backup: B:\barby\orchestrator\main.py.bak_20260723_*_charfeature
  • py_compile sauber.
  • Testinstanz auf Port 8198 (ORCH_PORT=8198), curl + Live-ComfyUI-Queue-Check bestanden, danach sauber beendet (taskkill).
  • Produktions-Restart ueber Scheduled Task BarbyOrchestrator (Stop-ScheduledTask / Start-ScheduledTask, PowerShell): alte PID 107992 beendet, neue PID 68816 auf Port 8197 -- PID-Wechsel bestaetigt echten Neustart.
  • cp.go-ki.eu (VM201-Portal) -> 200, /api/studio/characters -> 200 mit source:"orchestrator_live_scan" (Portal-Proxy greift bereits durch zum Orchestrator, kein Fallback-Manifest mehr noetig).

4. Portal-Dropdown live geprueft (Browser-MCP, cp.go-ki.eu)

Tab "🎬 Video" -> Subtab "🎬 Video Erstellen" -> Dropdown zeigt: Kein Charakter (KI entscheidet) / barby / businessman / nerd / passant / reporter JS-Fetch in der Seite bestaetigt: fetch('/api/studio/characters') -> {"source":"orchestrator_live_scan","count":5, "slugs":["barby","businessman","nerd","passant","reporter"]}

Ehrlicher Rest (nicht in diesem Ticket)

  • Nur barby ist completeness:"ready" (LoRA vorhanden). Die vier anderen (businessman, nerd, passant, reporter) sind consistency_method= "ipadapter_ref" OHNE Referenzbilder (refs_count:0, bootstrap_pending) -- waehlbar und die Pipeline nutzt jetzt echt ihre identity_tokens/Checkpoint, aber OHNE Gesichts-Konsistenz-Lock (kein Referenzbild/LoRA vorhanden). Fuer echte Konsistenz ueber mehrere Segmente braucht es noch den Bootstrap-Flow (POST /api/studio/characters/{slug}/bootstrap, siehe _portal_integration.json) -- der ist NICHT Teil dieses Auftrags und nicht gebaut. [BÄR]
  • _index.json (Cache) fuehrt noch 2 weitere Eintraege (whiteboard=Prop, schulklasse=Szene), die absichtlich NICHT im Charakter-Scan auftauchen (andere Kategorie/Ordner props/, scenes/) -- korrekt so laut Schema.

Dateien

  • B:\barby\orchestrator\main.py (geaendert, Backup siehe oben)
  • B:\barby\characters-library\characters\*\character.json (nur gelesen, nicht geaendert)