feat(comic): image-model picker — OpenAI + Nano Banana wählbar

Comic nutzte bisher 'openai/gpt-image-2' hartcodiert auf drei Ebenen
(generate-panel.ts, comic.generatePanel MCP-Tool, generate_comic_panel
AI-Tool). Wardrobe hat seit dem Nano-Banana-Commit einen
TryOnModelPicker mit drei Optionen — Comic spiegelt das jetzt 1:1.

Wählbar in allen drei Editoren (PanelEditor, BatchPanelEditor,
StoryboardSuggester):
- openai/gpt-image-2 (Default) — OpenAI GPT-image Standard
- google/gemini-3-pro-image-preview — Nano Banana Pro, hohe
  Konsistenz, teurer
- google/gemini-3.1-flash-image-preview — Nano Banana 2, neuestes,
  schnell, günstig

Implementierung:
- api/generate-panel.ts: PanelModel Union + DEFAULT_PANEL_MODEL +
  model? Param auf RunPanelGenerateParams + im HTTP-Body
  weitergereicht (vorher hart 'openai/gpt-image-2').
- components/PanelModelPicker.svelte: neue Komponente, Stil/Markup
  identisch zu TryOnModelPicker für Muskel-Memory über beide Flows.
- components/PanelEditor.svelte: `let model = $state(DEFAULT_PANEL_MODEL)`
  + Picker oberhalb der Qualität-/Format-Leiste + model im
  runPanelGenerate-Call.
- components/BatchPanelEditor.svelte: gleiche Änderung — ein Model
  pro Batch (nicht pro Row) damit der Batch konsistent rendert.
- components/StoryboardSuggester.svelte: gleiches Pattern; der
  Picker landet zwischen "Panel manuell"-Button und dem
  Qualität/Format-Block.
- packages/mana-tool-registry/src/modules/comic.ts: generatePanel
  Input-Schema bekommt model mit zod.enum() + default; im Body
  wird input.model durchgereicht.
- packages/shared-ai/src/tools/schemas.ts: generate_comic_panel
  bekommt Parameter 'model' optional mit gleicher Enum-Liste.
- apps/mana/apps/web/src/lib/modules/comic/tools.ts: isValidModel
  Guard + Parameter-Validierung; model an runPanelGenerate.

Keine Story-Level-Persistierung — model bleibt lokaler State pro
Editor-Mount. Eine model-Spalte auf comicStories würde Migration
brauchen und die Wahl ist eh ad-hoc pro Panel/Batch.

Plan-Doc (§2.1) dokumentiert die Entscheidung + die drei Optionen.

107 shared-ai tests weiter grün. check + validate:all clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-24 17:19:40 +02:00
parent 5501f472ae
commit 364522db87
9 changed files with 252 additions and 6 deletions

View file

@ -104,6 +104,27 @@ auseinanderdriften, adressieren wir das mit einer zusätzlichen
"Anchor-Panel"-Referenz (erstes erzeugtes Panel wird Referenz für alle
folgenden) — das ist M6+.
### 2.1 Image-Modell als Picker, nicht hartcodiert (nachgezogen)
Comic nutzt die gleiche Model-Auswahl wie Wardrobe's Try-On:
- `openai/gpt-image-2` — Default, mittlerer Preis, fällt server-seitig
auf gpt-image-1 zurück wenn die OpenAI-Org nicht verified ist.
- `google/gemini-3-pro-image-preview` — Nano Banana Pro, hohe
Charakter-Konsistenz, höherer Preis.
- `google/gemini-3.1-flash-image-preview` — Nano Banana 2, neuestes,
schnell, günstig.
`PanelModelPicker` (Analog zu `TryOnModelPicker`) sitzt als
segmentierter Picker in PanelEditor / BatchPanelEditor /
StoryboardSuggester. Die Wahl ist per-Editor-Mount lokal; keine
Story-Level-Persistierung, weil ein Model-Flag auf der Row eine
Migration bräuchte und die Wahl meistens eh ad-hoc ist.
MCP-Tool `comic.generatePanel` und Catalog-Tool `generate_comic_panel`
akzeptieren beide einen optionalen `model`-Parameter mit demselben
Enum. Default bleibt `openai/gpt-image-2`.
### 3. Fünf Stil-Presets, Mapping im Client
```typescript