@rslsp1/fa-app-tools 2.0.82 → 2.0.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-GEGJD43Y.mjs → chunk-JTGC5PXJ.mjs} +602 -10
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +594 -13
- package/dist/index.mjs +5 -4
- package/dist/szenen.d.mts +183 -8
- package/dist/szenen.d.ts +183 -8
- package/dist/szenen.js +388 -28
- package/dist/szenen.mjs +47 -258
- package/package.json +1 -1
|
@@ -95,13 +95,13 @@ function noticeFor(ergebnis, was) {
|
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
case "rejected": {
|
|
98
|
-
const
|
|
98
|
+
const fehler4 = ergebnis.errors ?? [];
|
|
99
99
|
const ungeprueft = ergebnis.unchecked ?? [];
|
|
100
100
|
return {
|
|
101
101
|
tone: "rejected",
|
|
102
|
-
text: `${was}: abgelehnt \u2014 ${
|
|
102
|
+
text: `${was}: abgelehnt \u2014 ${fehler4.length} Befund${fehler4.length === 1 ? "" : "e"}.`,
|
|
103
103
|
details: [
|
|
104
|
-
...
|
|
104
|
+
...fehler4.map((f) => `${f.path ?? "(ohne Pfad)"}: ${f.message ?? "ohne Meldung"}`),
|
|
105
105
|
// Nicht verschweigen: was nicht geprüft wurde, ist nicht in Ordnung,
|
|
106
106
|
// sondern ungeprüft.
|
|
107
107
|
...ungeprueft.map((u) => `ungepr\xFCft: ${u}`)
|
|
@@ -4422,7 +4422,30 @@ var SZENEN_EVENT_TYPES = {
|
|
|
4422
4422
|
* ebenfalls keine Bilddaten — nur Status, Zaehlung und die Item-Kennung,
|
|
4423
4423
|
* falls eine entstand.
|
|
4424
4424
|
*/
|
|
4425
|
-
imageGenerationFinished: "szenen.image_generation_finished"
|
|
4425
|
+
imageGenerationFinished: "szenen.image_generation_finished",
|
|
4426
|
+
/**
|
|
4427
|
+
* Ein Bild-Batch ist kanonisch gespeichert — Stufe 6.9.2, Gate D
|
|
4428
|
+
* (D-6.9.2-6).
|
|
4429
|
+
*
|
|
4430
|
+
* Erscheint erst, **nachdem** jedes Bild des Batches im Bildbestand liegt
|
|
4431
|
+
* (`hfUploadImage` + `image_added`, dieselbe Reihenfolge wie
|
|
4432
|
+
* `hfImageLibrary.putImage`) — kein Bild gilt als vorhanden, bevor sein
|
|
4433
|
+
* Upload bestätigt ist (R3). Trägt bewusst **keine Bilddaten**, nur den
|
|
4434
|
+
* vollständigen Metadatennachweis, den `listBatchesForPromptRun()` /
|
|
4435
|
+
* `getBatch()` ohne MySQL rekonstruieren können müssen: `item_id`,
|
|
4436
|
+
* `prompt_run_id`, `generation_batch_id`, `source_kind`, je Bild
|
|
4437
|
+
* `position`, `media_ref`, `asset_id`, `model`, `seed`, `width`/`height`.
|
|
4438
|
+
*
|
|
4439
|
+
* Additiv wie jedes Ereignis dieser Domain: ein zweiter Batch desselben
|
|
4440
|
+
* Laufs ist ein **weiteres** Ereignis mit derselben `item_id`, nicht eine
|
|
4441
|
+
* Änderung am ersten (D-113/D-121 — ein Lauf bleibt ein Item). Gilt für
|
|
4442
|
+
* `generated_in_app` **und** `external_import` — nur `source_kind`
|
|
4443
|
+
* unterscheidet die beiden Schreiber (D-116/D-117/D-120).
|
|
4444
|
+
*
|
|
4445
|
+
* Der Elementreducer ignoriert auch diesen Typ (`default:`-Zweig); gelesen
|
|
4446
|
+
* wird mit `collectImageBatches` (`imageBatchStore.ts`).
|
|
4447
|
+
*/
|
|
4448
|
+
imageBatchPersisted: "szenen.image_batch_persisted"
|
|
4426
4449
|
};
|
|
4427
4450
|
function sortForReplay(events) {
|
|
4428
4451
|
return [...events].sort((a, b) => {
|
|
@@ -6132,7 +6155,7 @@ var ERKLAERUNG = {
|
|
|
6132
6155
|
};
|
|
6133
6156
|
var CapabilityPanel = ({ port, elementId, setupPayload }) => {
|
|
6134
6157
|
const [bericht, setBericht] = useState4(null);
|
|
6135
|
-
const [
|
|
6158
|
+
const [fehler4, setFehler] = useState4(null);
|
|
6136
6159
|
useEffect2(() => {
|
|
6137
6160
|
let abgemeldet = false;
|
|
6138
6161
|
setBericht(null);
|
|
@@ -6154,10 +6177,10 @@ var CapabilityPanel = ({ port, elementId, setupPayload }) => {
|
|
|
6154
6177
|
abgemeldet = true;
|
|
6155
6178
|
};
|
|
6156
6179
|
}, [port, elementId, setupPayload]);
|
|
6157
|
-
if (
|
|
6180
|
+
if (fehler4) {
|
|
6158
6181
|
return /* @__PURE__ */ jsxs3("p", { "data-testid": "capability-fehler", role: "alert", children: [
|
|
6159
6182
|
"F\xE4higkeitsbericht nicht erstellbar: ",
|
|
6160
|
-
|
|
6183
|
+
fehler4
|
|
6161
6184
|
] });
|
|
6162
6185
|
}
|
|
6163
6186
|
if (!bericht) return /* @__PURE__ */ jsx3("p", { "data-testid": "capability-laden", children: "F\xE4higkeitsbericht wird erstellt \u2026" });
|
|
@@ -6659,10 +6682,10 @@ var ZuordnenAktion = ({ port, lauf, onFertig }) => {
|
|
|
6659
6682
|
setNotiz(
|
|
6660
6683
|
ergebnis.kind === "ok" ? { tone: "ok", text: `Importiert als Item ${ergebnis.value.item_id} mit ${bilder.length} Bild(ern).` } : noticeFor(ergebnis, "Externe Bilder importieren")
|
|
6661
6684
|
);
|
|
6662
|
-
} catch (
|
|
6685
|
+
} catch (fehler4) {
|
|
6663
6686
|
setNotiz({
|
|
6664
6687
|
tone: "error",
|
|
6665
|
-
text: `Externe Bilder importieren: ${
|
|
6688
|
+
text: `Externe Bilder importieren: ${fehler4 instanceof Error ? fehler4.message : String(fehler4)}`
|
|
6666
6689
|
});
|
|
6667
6690
|
}
|
|
6668
6691
|
setLaeuft(false);
|
|
@@ -11138,6 +11161,532 @@ function createHfImageLibrary(options) {
|
|
|
11138
11161
|
};
|
|
11139
11162
|
}
|
|
11140
11163
|
|
|
11164
|
+
// src/lib/szenen/flowImageProvider.ts
|
|
11165
|
+
var FLOW_MODEL_DISPLAY_NAMES = {
|
|
11166
|
+
"imagen-4.0-generate-001": "Imagen 4"
|
|
11167
|
+
};
|
|
11168
|
+
function flowImageProviderHasAccess(model) {
|
|
11169
|
+
return model.callable_model_id in FLOW_MODEL_DISPLAY_NAMES;
|
|
11170
|
+
}
|
|
11171
|
+
function istNichtleererText(wert) {
|
|
11172
|
+
return typeof wert === "string" && wert.trim().length > 0;
|
|
11173
|
+
}
|
|
11174
|
+
function createFlowImageProvider(generateImage) {
|
|
11175
|
+
return {
|
|
11176
|
+
async generate(input) {
|
|
11177
|
+
const modelDisplayName = FLOW_MODEL_DISPLAY_NAMES[input.callableModelId];
|
|
11178
|
+
if (!modelDisplayName) {
|
|
11179
|
+
throw new Error(
|
|
11180
|
+
`Der Flow-Host kennt keinen Flow-Display-Namen zu "${input.callableModelId}". Bekannt sind: ${Object.keys(FLOW_MODEL_DISPLAY_NAMES).join(", ")}. Es wird kein anderes Modell ersatzweise gerufen (D-115/D-6.9.2-3).`
|
|
11181
|
+
);
|
|
11182
|
+
}
|
|
11183
|
+
if (istNichtleererText(input.negativePrompt)) {
|
|
11184
|
+
throw new Error(
|
|
11185
|
+
"Flow.generate.image kennt keinen dokumentierten Parameter f\xFCr einen negativen Prompt. Der Auftrag wird deshalb als fehlgeschlagen protokolliert, statt den negativen Prompt still zu verlieren (D-6.9.2-3)."
|
|
11186
|
+
);
|
|
11187
|
+
}
|
|
11188
|
+
const erzeugt = [];
|
|
11189
|
+
let ersterFehler = null;
|
|
11190
|
+
for (let position = 0; position < input.imageCount; position++) {
|
|
11191
|
+
try {
|
|
11192
|
+
const antwort = await generateImage({
|
|
11193
|
+
prompt: input.positivePrompt,
|
|
11194
|
+
modelDisplayName,
|
|
11195
|
+
...input.aspectRatio ? { aspectRatio: input.aspectRatio } : {}
|
|
11196
|
+
});
|
|
11197
|
+
if (!antwort || typeof antwort.base64 !== "string" || antwort.base64.length === 0) {
|
|
11198
|
+
throw new Error("Flow.generate.image hat kein Bild geliefert.");
|
|
11199
|
+
}
|
|
11200
|
+
erzeugt.push({
|
|
11201
|
+
imageBase64: antwort.base64,
|
|
11202
|
+
// Das tatsaechlich gerufene Modell, nicht der Flow-Display-Name —
|
|
11203
|
+
// im Bestand soll stehen, was bezahlt wurde (wie reactImageProvider.ts).
|
|
11204
|
+
model: input.callableModelId
|
|
11205
|
+
// Kein Seed: weder als Eingabe dokumentiert noch als Ausgabe
|
|
11206
|
+
// geliefert — nichts wird erfunden (D-107).
|
|
11207
|
+
});
|
|
11208
|
+
} catch (fehler4) {
|
|
11209
|
+
ersterFehler = fehler4 instanceof Error ? fehler4.message : String(fehler4);
|
|
11210
|
+
break;
|
|
11211
|
+
}
|
|
11212
|
+
}
|
|
11213
|
+
if (erzeugt.length === 0) {
|
|
11214
|
+
throw new Error(
|
|
11215
|
+
ersterFehler ?? `Flow.generate.image hat zu ${input.callableModelId} kein verwertbares Bild geliefert.`
|
|
11216
|
+
);
|
|
11217
|
+
}
|
|
11218
|
+
return { images: erzeugt };
|
|
11219
|
+
}
|
|
11220
|
+
};
|
|
11221
|
+
}
|
|
11222
|
+
|
|
11223
|
+
// src/lib/szenen/imageGenerationOrderStore.ts
|
|
11224
|
+
function istText3(wert) {
|
|
11225
|
+
return typeof wert === "string" && wert.trim().length > 0;
|
|
11226
|
+
}
|
|
11227
|
+
function collectImageGenerationOrders(events) {
|
|
11228
|
+
const byBatchId = /* @__PURE__ */ new Map();
|
|
11229
|
+
for (const event of events) {
|
|
11230
|
+
if (event.type !== SZENEN_EVENT_TYPES.imageGenerationStarted) continue;
|
|
11231
|
+
const payload = event.payload;
|
|
11232
|
+
if (!payload || !istText3(payload.generation_batch_id) || !istText3(payload.prompt_run_id)) continue;
|
|
11233
|
+
if (byBatchId.has(payload.generation_batch_id)) continue;
|
|
11234
|
+
byBatchId.set(payload.generation_batch_id, {
|
|
11235
|
+
generation_batch_id: payload.generation_batch_id,
|
|
11236
|
+
prompt_run_id: payload.prompt_run_id,
|
|
11237
|
+
source_kind: "generated_in_app",
|
|
11238
|
+
request: payload.request,
|
|
11239
|
+
created_at: payload.created_at ?? "",
|
|
11240
|
+
status: "started"
|
|
11241
|
+
});
|
|
11242
|
+
}
|
|
11243
|
+
for (const event of events) {
|
|
11244
|
+
if (event.type !== SZENEN_EVENT_TYPES.imageGenerationFinished) continue;
|
|
11245
|
+
const payload = event.payload;
|
|
11246
|
+
if (!payload || !istText3(payload.generation_batch_id)) continue;
|
|
11247
|
+
const auftrag = byBatchId.get(payload.generation_batch_id);
|
|
11248
|
+
if (!auftrag) continue;
|
|
11249
|
+
if (auftrag.status !== "started") continue;
|
|
11250
|
+
if (payload.status !== "succeeded" && payload.status !== "partial" && payload.status !== "failed") continue;
|
|
11251
|
+
byBatchId.set(payload.generation_batch_id, {
|
|
11252
|
+
...auftrag,
|
|
11253
|
+
status: payload.status,
|
|
11254
|
+
...payload.item_id ? { item_id: payload.item_id } : {},
|
|
11255
|
+
produced_count: payload.produced_count ?? 0,
|
|
11256
|
+
...payload.diagnostic ? { diagnostic: payload.diagnostic } : {},
|
|
11257
|
+
finished_at: payload.finished_at ?? ""
|
|
11258
|
+
});
|
|
11259
|
+
}
|
|
11260
|
+
return [...byBatchId.values()];
|
|
11261
|
+
}
|
|
11262
|
+
function ordersForPromptRun(events, runId) {
|
|
11263
|
+
return collectImageGenerationOrders(events).filter((o) => o.prompt_run_id === runId);
|
|
11264
|
+
}
|
|
11265
|
+
function findImageGenerationOrder(events, batchId) {
|
|
11266
|
+
return collectImageGenerationOrders(events).find((o) => o.generation_batch_id === batchId) ?? null;
|
|
11267
|
+
}
|
|
11268
|
+
|
|
11269
|
+
// src/lib/szenen/imageBatchStore.ts
|
|
11270
|
+
var istText4 = (wert) => typeof wert === "string" && wert.trim().length > 0;
|
|
11271
|
+
function alsBilder(rohe) {
|
|
11272
|
+
if (!Array.isArray(rohe)) return [];
|
|
11273
|
+
return rohe.filter((b) => !!b && typeof b === "object").filter((b) => istText4(b.media_ref) && typeof b.position === "number").map((b) => ({
|
|
11274
|
+
media_ref: b.media_ref,
|
|
11275
|
+
position: b.position,
|
|
11276
|
+
...istText4(b.asset_id) ? { asset_id: b.asset_id } : {},
|
|
11277
|
+
model: b.model ?? null,
|
|
11278
|
+
seed: b.seed ?? null,
|
|
11279
|
+
width: b.width ?? null,
|
|
11280
|
+
height: b.height ?? null
|
|
11281
|
+
}));
|
|
11282
|
+
}
|
|
11283
|
+
function collectImageBatches(events) {
|
|
11284
|
+
const byItemId = /* @__PURE__ */ new Map();
|
|
11285
|
+
for (const event of events) {
|
|
11286
|
+
if (event.type !== SZENEN_EVENT_TYPES.imageBatchPersisted) continue;
|
|
11287
|
+
const payload = event.payload;
|
|
11288
|
+
if (!payload || !istText4(payload.item_id) || !istText4(payload.prompt_run_id) || !istText4(payload.generation_batch_id)) continue;
|
|
11289
|
+
if (payload.source_kind !== "generated_in_app" && payload.source_kind !== "external_import") continue;
|
|
11290
|
+
const bestehend = byItemId.get(payload.item_id);
|
|
11291
|
+
if (bestehend?.generation_batch_ids.includes(payload.generation_batch_id)) continue;
|
|
11292
|
+
const bilder = alsBilder(payload.images);
|
|
11293
|
+
if (!bestehend) {
|
|
11294
|
+
byItemId.set(payload.item_id, {
|
|
11295
|
+
item_id: payload.item_id,
|
|
11296
|
+
prompt_run_id: payload.prompt_run_id,
|
|
11297
|
+
generation_batch_ids: [payload.generation_batch_id],
|
|
11298
|
+
source_kind: payload.source_kind,
|
|
11299
|
+
title: istText4(payload.title) ? payload.title : `Batch aus Lauf ${payload.prompt_run_id}`,
|
|
11300
|
+
images: bilder
|
|
11301
|
+
});
|
|
11302
|
+
continue;
|
|
11303
|
+
}
|
|
11304
|
+
byItemId.set(payload.item_id, {
|
|
11305
|
+
...bestehend,
|
|
11306
|
+
generation_batch_ids: [...bestehend.generation_batch_ids, payload.generation_batch_id],
|
|
11307
|
+
images: [...bestehend.images, ...bilder]
|
|
11308
|
+
});
|
|
11309
|
+
}
|
|
11310
|
+
return [...byItemId.values()];
|
|
11311
|
+
}
|
|
11312
|
+
function batchesForPromptRun(events, runId) {
|
|
11313
|
+
return collectImageBatches(events).filter((b) => b.prompt_run_id === runId);
|
|
11314
|
+
}
|
|
11315
|
+
function findImageBatch(events, batchId) {
|
|
11316
|
+
return collectImageBatches(events).find((b) => b.generation_batch_ids.includes(batchId)) ?? null;
|
|
11317
|
+
}
|
|
11318
|
+
|
|
11319
|
+
// src/lib/szenen/hfImageBatchHistory.ts
|
|
11320
|
+
function lesefehler(aktion, error) {
|
|
11321
|
+
return {
|
|
11322
|
+
kind: "error",
|
|
11323
|
+
message: `${aktion}: ${error instanceof Error ? error.message : String(error)}`,
|
|
11324
|
+
retryable: true
|
|
11325
|
+
};
|
|
11326
|
+
}
|
|
11327
|
+
function createHfImageBatchHistory(options) {
|
|
11328
|
+
const { channel } = options;
|
|
11329
|
+
return {
|
|
11330
|
+
async listBatchesForPromptRun(runId) {
|
|
11331
|
+
try {
|
|
11332
|
+
const events = await channel.readEvents();
|
|
11333
|
+
return { kind: "ok", value: batchesForPromptRun(events, runId) };
|
|
11334
|
+
} catch (error) {
|
|
11335
|
+
return lesefehler(`Batches fuer Lauf ${runId} konnten nicht gelesen werden`, error);
|
|
11336
|
+
}
|
|
11337
|
+
},
|
|
11338
|
+
async getBatch(batchId) {
|
|
11339
|
+
try {
|
|
11340
|
+
const events = await channel.readEvents();
|
|
11341
|
+
return { kind: "ok", value: findImageBatch(events, batchId) };
|
|
11342
|
+
} catch (error) {
|
|
11343
|
+
return lesefehler(`Batch ${batchId} konnte nicht gelesen werden`, error);
|
|
11344
|
+
}
|
|
11345
|
+
},
|
|
11346
|
+
async listOrdersForPromptRun(runId) {
|
|
11347
|
+
try {
|
|
11348
|
+
const events = await channel.readEvents();
|
|
11349
|
+
return { kind: "ok", value: ordersForPromptRun(events, runId) };
|
|
11350
|
+
} catch (error) {
|
|
11351
|
+
return lesefehler(`Bildgenerierungsauftraege fuer Lauf ${runId} konnten nicht gelesen werden`, error);
|
|
11352
|
+
}
|
|
11353
|
+
}
|
|
11354
|
+
};
|
|
11355
|
+
}
|
|
11356
|
+
|
|
11357
|
+
// src/lib/szenen/hfImageBatchPersistence.ts
|
|
11358
|
+
function fehler3(nachricht, retryable = true) {
|
|
11359
|
+
return { kind: "error", message: nachricht, retryable };
|
|
11360
|
+
}
|
|
11361
|
+
async function legeBatchAb(options, input) {
|
|
11362
|
+
const { namespace, token, channel } = options;
|
|
11363
|
+
const newImageId = options.newImageId ?? ((batchId, position) => `${batchId}-${position}`);
|
|
11364
|
+
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
11365
|
+
const itemId = itemIdForRun(input.runId);
|
|
11366
|
+
let vorhandeneEvents;
|
|
11367
|
+
try {
|
|
11368
|
+
vorhandeneEvents = await channel.readEvents();
|
|
11369
|
+
} catch (error) {
|
|
11370
|
+
return fehler3(
|
|
11371
|
+
`Bild-Batches von Lauf ${input.runId} konnten vor dem Ablegen nicht gelesen werden: ${error instanceof Error ? error.message : String(error)}`
|
|
11372
|
+
);
|
|
11373
|
+
}
|
|
11374
|
+
const bestehend = batchesForPromptRun(vorhandeneEvents, input.runId)[0] ?? null;
|
|
11375
|
+
if (bestehend?.generation_batch_ids.includes(input.generationBatchId)) {
|
|
11376
|
+
return { kind: "ok", value: bestehend };
|
|
11377
|
+
}
|
|
11378
|
+
const startPosition = bestehend?.images.length ?? 0;
|
|
11379
|
+
const abgelegt = [];
|
|
11380
|
+
for (let offset = 0; offset < input.images.length; offset++) {
|
|
11381
|
+
const bild = input.images[offset];
|
|
11382
|
+
const id = newImageId(input.generationBatchId, startPosition + offset);
|
|
11383
|
+
try {
|
|
11384
|
+
await hfUploadImage(bild.imageBase64, id, token, bild.mimeType);
|
|
11385
|
+
await writeHFEvent(namespace, token, "image_added", {
|
|
11386
|
+
id,
|
|
11387
|
+
prompt: input.title ?? `Batch ${input.generationBatchId}`,
|
|
11388
|
+
tags: [],
|
|
11389
|
+
timestamp: now().getTime(),
|
|
11390
|
+
mimeType: bild.mimeType
|
|
11391
|
+
}, []);
|
|
11392
|
+
} catch (error) {
|
|
11393
|
+
return fehler3(
|
|
11394
|
+
`Bild ${offset + 1}/${input.images.length} des Batches ${input.generationBatchId} konnte nicht im Bildbestand abgelegt werden: ${error instanceof Error ? error.message : String(error)}. Bereits abgelegte Bilder dieses Versuchs (${abgelegt.length}) bleiben im Bestand, geh\xF6ren aber zu keinem Batch, solange das Batch-Ereignis nicht geschrieben ist.`
|
|
11395
|
+
);
|
|
11396
|
+
}
|
|
11397
|
+
abgelegt.push({
|
|
11398
|
+
position: startPosition + offset,
|
|
11399
|
+
media_ref: id,
|
|
11400
|
+
asset_id: id,
|
|
11401
|
+
model: bild.model ?? null,
|
|
11402
|
+
seed: bild.seed ?? null,
|
|
11403
|
+
width: bild.width ?? null,
|
|
11404
|
+
height: bild.height ?? null
|
|
11405
|
+
});
|
|
11406
|
+
}
|
|
11407
|
+
const titel = bestehend?.title ?? (input.title?.trim() || `Batch aus Lauf ${input.runId}`);
|
|
11408
|
+
const payload = {
|
|
11409
|
+
item_id: itemId,
|
|
11410
|
+
prompt_run_id: input.runId,
|
|
11411
|
+
generation_batch_id: input.generationBatchId,
|
|
11412
|
+
source_kind: input.sourceKind,
|
|
11413
|
+
title: titel,
|
|
11414
|
+
images: abgelegt,
|
|
11415
|
+
created_at: now().toISOString()
|
|
11416
|
+
};
|
|
11417
|
+
try {
|
|
11418
|
+
await channel.appendEvent(SZENEN_EVENT_TYPES.imageBatchPersisted, payload);
|
|
11419
|
+
} catch (error) {
|
|
11420
|
+
return fehler3(
|
|
11421
|
+
`Die Batch-Metadaten fuer ${input.generationBatchId} konnten nicht protokolliert werden, obwohl die Bilder bereits im Bestand liegen: ${error instanceof Error ? error.message : String(error)}`
|
|
11422
|
+
);
|
|
11423
|
+
}
|
|
11424
|
+
const zusammengefuehrt = {
|
|
11425
|
+
item_id: itemId,
|
|
11426
|
+
prompt_run_id: input.runId,
|
|
11427
|
+
generation_batch_ids: bestehend ? [...bestehend.generation_batch_ids, input.generationBatchId] : [input.generationBatchId],
|
|
11428
|
+
source_kind: bestehend?.source_kind ?? input.sourceKind,
|
|
11429
|
+
title: titel,
|
|
11430
|
+
images: [...bestehend?.images ?? [], ...abgelegt]
|
|
11431
|
+
};
|
|
11432
|
+
return { kind: "ok", value: zusammengefuehrt };
|
|
11433
|
+
}
|
|
11434
|
+
function createHfImageGenerationBatchPersistence(options) {
|
|
11435
|
+
return {
|
|
11436
|
+
async persist(input) {
|
|
11437
|
+
return legeBatchAb(options, {
|
|
11438
|
+
runId: input.runId,
|
|
11439
|
+
generationBatchId: input.generationBatchId,
|
|
11440
|
+
sourceKind: "generated_in_app",
|
|
11441
|
+
images: input.images.map((bild) => ({
|
|
11442
|
+
imageBase64: bild.imageBase64,
|
|
11443
|
+
// Flow liefert PNG-Base64 (bestehende Konvention, s. AvatarArchitectApp.tsx
|
|
11444
|
+
// `data:image/png;base64,${base64}`); der gemeinsame Vertrag führt
|
|
11445
|
+
// keinen MIME-Typ je Bild.
|
|
11446
|
+
mimeType: "image/png",
|
|
11447
|
+
model: bild.model ?? null,
|
|
11448
|
+
seed: bild.seed ?? null,
|
|
11449
|
+
width: bild.width ?? null,
|
|
11450
|
+
height: bild.height ?? null
|
|
11451
|
+
}))
|
|
11452
|
+
});
|
|
11453
|
+
}
|
|
11454
|
+
};
|
|
11455
|
+
}
|
|
11456
|
+
function createHfImageBatchWrite(options) {
|
|
11457
|
+
return {
|
|
11458
|
+
async importBatch(input) {
|
|
11459
|
+
return legeBatchAb(options, {
|
|
11460
|
+
runId: input.runId,
|
|
11461
|
+
generationBatchId: input.generationBatchId,
|
|
11462
|
+
sourceKind: "external_import",
|
|
11463
|
+
title: input.title,
|
|
11464
|
+
images: input.images.map((bild) => ({
|
|
11465
|
+
imageBase64: bild.imageBase64,
|
|
11466
|
+
mimeType: "image/png",
|
|
11467
|
+
model: bild.model ?? null,
|
|
11468
|
+
seed: bild.seed ?? null,
|
|
11469
|
+
width: bild.width ?? null,
|
|
11470
|
+
height: bild.height ?? null
|
|
11471
|
+
}))
|
|
11472
|
+
});
|
|
11473
|
+
},
|
|
11474
|
+
async attachLibraryItem(input) {
|
|
11475
|
+
let events;
|
|
11476
|
+
try {
|
|
11477
|
+
events = await options.channel.readEvents();
|
|
11478
|
+
} catch (error) {
|
|
11479
|
+
return {
|
|
11480
|
+
kind: "error",
|
|
11481
|
+
message: `Batches konnten nicht gelesen werden: ${error instanceof Error ? error.message : String(error)}`,
|
|
11482
|
+
retryable: true
|
|
11483
|
+
};
|
|
11484
|
+
}
|
|
11485
|
+
const item = collectImageBatches(events).find((b) => b.item_id === input.itemId);
|
|
11486
|
+
if (!item) {
|
|
11487
|
+
return { kind: "error", message: `Item ${input.itemId} ist unbekannt.`, retryable: false };
|
|
11488
|
+
}
|
|
11489
|
+
if (item.prompt_run_id !== input.runId) {
|
|
11490
|
+
return {
|
|
11491
|
+
kind: "conflict",
|
|
11492
|
+
message: `Item ${input.itemId} geh\xF6rt bereits zu Lauf ${item.prompt_run_id}.`,
|
|
11493
|
+
existingPromptRunId: item.prompt_run_id
|
|
11494
|
+
};
|
|
11495
|
+
}
|
|
11496
|
+
return { kind: "ok", value: item };
|
|
11497
|
+
}
|
|
11498
|
+
};
|
|
11499
|
+
}
|
|
11500
|
+
|
|
11501
|
+
// src/lib/szenen/imageGenerationCapability.ts
|
|
11502
|
+
var isObject9 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
11503
|
+
var IMAGE_MODEL_CATALOGUE = {
|
|
11504
|
+
imagen_4: {
|
|
11505
|
+
callable_model_id: "imagen-4.0-generate-001",
|
|
11506
|
+
provider: "google",
|
|
11507
|
+
max_images: 4,
|
|
11508
|
+
aspect_ratios: ["1:1", "3:4", "4:3", "9:16", "16:9"],
|
|
11509
|
+
supports_seed: true
|
|
11510
|
+
},
|
|
11511
|
+
imagen_3: {
|
|
11512
|
+
callable_model_id: "imagen-3.0-generate-001",
|
|
11513
|
+
provider: "google",
|
|
11514
|
+
max_images: 4,
|
|
11515
|
+
aspect_ratios: ["1:1", "3:4", "4:3", "9:16", "16:9"],
|
|
11516
|
+
supports_seed: true
|
|
11517
|
+
}
|
|
11518
|
+
};
|
|
11519
|
+
function callableImageModelFor(targetModelKey) {
|
|
11520
|
+
return IMAGE_MODEL_CATALOGUE[targetModelKey] ?? null;
|
|
11521
|
+
}
|
|
11522
|
+
function targetModelKeyOf(targetModel) {
|
|
11523
|
+
if (!isObject9(targetModel)) return null;
|
|
11524
|
+
return typeof targetModel.key === "string" && targetModel.key.length > 0 ? targetModel.key : null;
|
|
11525
|
+
}
|
|
11526
|
+
function capabilityForTargetModel(targetModel, hasAccess) {
|
|
11527
|
+
const key = targetModelKeyOf(targetModel);
|
|
11528
|
+
if (!key) {
|
|
11529
|
+
return {
|
|
11530
|
+
kind: "unsupported",
|
|
11531
|
+
target_model_key: "(unbekannt)",
|
|
11532
|
+
reason: 'Der eingefrorene Lauf tr\xE4gt kein "target_model.key" \u2014 es gibt nichts zuzuordnen.'
|
|
11533
|
+
};
|
|
11534
|
+
}
|
|
11535
|
+
const modell = callableImageModelFor(key);
|
|
11536
|
+
if (!modell) {
|
|
11537
|
+
return {
|
|
11538
|
+
kind: "unsupported",
|
|
11539
|
+
target_model_key: key,
|
|
11540
|
+
reason: `F\xFCr das Zielmodell "${key}" ist in diesem Host kein Bildpfad katalogisiert.`
|
|
11541
|
+
};
|
|
11542
|
+
}
|
|
11543
|
+
if (!hasAccess(modell)) {
|
|
11544
|
+
return {
|
|
11545
|
+
kind: "unsupported",
|
|
11546
|
+
target_model_key: key,
|
|
11547
|
+
reason: `Dieser Host hat keinen Zugang zu ${modell.callable_model_id} (${modell.provider}).`
|
|
11548
|
+
};
|
|
11549
|
+
}
|
|
11550
|
+
return {
|
|
11551
|
+
kind: "supported",
|
|
11552
|
+
target_model_key: key,
|
|
11553
|
+
provider: modell.provider,
|
|
11554
|
+
callable_model_id: modell.callable_model_id,
|
|
11555
|
+
max_images: modell.max_images,
|
|
11556
|
+
aspect_ratios: modell.aspect_ratios,
|
|
11557
|
+
supports_seed: modell.supports_seed
|
|
11558
|
+
};
|
|
11559
|
+
}
|
|
11560
|
+
|
|
11561
|
+
// src/lib/szenen/imageGenerationPort.ts
|
|
11562
|
+
function queryError2(error, action) {
|
|
11563
|
+
return {
|
|
11564
|
+
kind: "error",
|
|
11565
|
+
message: `${action}: ${error instanceof Error ? error.message : String(error)}`,
|
|
11566
|
+
retryable: true
|
|
11567
|
+
};
|
|
11568
|
+
}
|
|
11569
|
+
function createImageGenerationPort(options) {
|
|
11570
|
+
const { runs, provider, batches, events, hasAccess } = options;
|
|
11571
|
+
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
11572
|
+
async function readRun(runId) {
|
|
11573
|
+
try {
|
|
11574
|
+
return await runs.getRun(runId);
|
|
11575
|
+
} catch (error) {
|
|
11576
|
+
return queryError2(error, `Lauf ${runId} konnte nicht gelesen werden`);
|
|
11577
|
+
}
|
|
11578
|
+
}
|
|
11579
|
+
return {
|
|
11580
|
+
async capabilityForRun(runId) {
|
|
11581
|
+
const gelesen = await readRun(runId);
|
|
11582
|
+
if (gelesen.kind !== "ok") return gelesen;
|
|
11583
|
+
if (!gelesen.value) {
|
|
11584
|
+
return { kind: "error", message: `Lauf ${runId} ist unbekannt.`, retryable: false };
|
|
11585
|
+
}
|
|
11586
|
+
const targetModel = gelesen.value.input_payload?.target_model;
|
|
11587
|
+
return { kind: "ok", value: capabilityForTargetModel(targetModel, hasAccess) };
|
|
11588
|
+
},
|
|
11589
|
+
async startFromPromptRun(input) {
|
|
11590
|
+
const gelesen = await readRun(input.runId);
|
|
11591
|
+
if (gelesen.kind !== "ok") return { kind: "rejected", message: gelesen.message };
|
|
11592
|
+
if (!gelesen.value) {
|
|
11593
|
+
return { kind: "rejected", message: `Lauf ${input.runId} ist unbekannt.` };
|
|
11594
|
+
}
|
|
11595
|
+
const run = gelesen.value;
|
|
11596
|
+
if (run.status !== "succeeded" || !run.output) {
|
|
11597
|
+
return {
|
|
11598
|
+
kind: "rejected",
|
|
11599
|
+
message: `Lauf ${input.runId} ist nicht erfolgreich \u2014 ein Bildauftrag braucht einen eingefrorenen Prompt (D-103).`
|
|
11600
|
+
};
|
|
11601
|
+
}
|
|
11602
|
+
const targetModel = run.input_payload?.target_model;
|
|
11603
|
+
const capability = capabilityForTargetModel(targetModel, hasAccess);
|
|
11604
|
+
if (capability.kind !== "supported") {
|
|
11605
|
+
return { kind: "unsupported", targetModelKey: capability.target_model_key, reason: capability.reason };
|
|
11606
|
+
}
|
|
11607
|
+
const startedPayload = {
|
|
11608
|
+
generation_batch_id: input.generationBatchId,
|
|
11609
|
+
prompt_run_id: input.runId,
|
|
11610
|
+
source_kind: "generated_in_app",
|
|
11611
|
+
request: {
|
|
11612
|
+
image_count: input.imageCount,
|
|
11613
|
+
...input.aspectRatio ? { aspect_ratio: input.aspectRatio } : {},
|
|
11614
|
+
...input.seeds ? { seeds: input.seeds } : {},
|
|
11615
|
+
callable_model_id: capability.callable_model_id
|
|
11616
|
+
},
|
|
11617
|
+
created_at: now().toISOString()
|
|
11618
|
+
};
|
|
11619
|
+
try {
|
|
11620
|
+
await events.appendEvent(SZENEN_EVENT_TYPES.imageGenerationStarted, startedPayload);
|
|
11621
|
+
} catch (error) {
|
|
11622
|
+
return {
|
|
11623
|
+
kind: "failed",
|
|
11624
|
+
message: `Der Auftrag ${input.generationBatchId} konnte nicht protokolliert werden: ${error instanceof Error ? error.message : String(error)}`
|
|
11625
|
+
};
|
|
11626
|
+
}
|
|
11627
|
+
let produced = [];
|
|
11628
|
+
let providerFehler = null;
|
|
11629
|
+
try {
|
|
11630
|
+
const antwort = await provider.generate({
|
|
11631
|
+
callableModelId: capability.callable_model_id,
|
|
11632
|
+
provider: capability.provider,
|
|
11633
|
+
positivePrompt: run.output.positive,
|
|
11634
|
+
negativePrompt: run.output.negative,
|
|
11635
|
+
imageCount: input.imageCount,
|
|
11636
|
+
...input.aspectRatio ? { aspectRatio: input.aspectRatio } : {},
|
|
11637
|
+
...input.seeds ? { seeds: input.seeds } : {}
|
|
11638
|
+
});
|
|
11639
|
+
produced = antwort.images;
|
|
11640
|
+
} catch (error) {
|
|
11641
|
+
providerFehler = error instanceof Error ? error.message : String(error);
|
|
11642
|
+
}
|
|
11643
|
+
if (providerFehler || produced.length === 0) {
|
|
11644
|
+
const finishedPayload2 = {
|
|
11645
|
+
generation_batch_id: input.generationBatchId,
|
|
11646
|
+
status: "failed",
|
|
11647
|
+
produced_count: 0,
|
|
11648
|
+
diagnostic: providerFehler ?? "Der Provider hat kein verwertbares Bild geliefert.",
|
|
11649
|
+
finished_at: now().toISOString()
|
|
11650
|
+
};
|
|
11651
|
+
await events.appendEvent(SZENEN_EVENT_TYPES.imageGenerationFinished, finishedPayload2).catch(() => {
|
|
11652
|
+
});
|
|
11653
|
+
return {
|
|
11654
|
+
kind: "failed",
|
|
11655
|
+
message: finishedPayload2.diagnostic
|
|
11656
|
+
};
|
|
11657
|
+
}
|
|
11658
|
+
const persistiert = await batches.persist({
|
|
11659
|
+
runId: input.runId,
|
|
11660
|
+
generationBatchId: input.generationBatchId,
|
|
11661
|
+
images: produced
|
|
11662
|
+
});
|
|
11663
|
+
if (persistiert.kind !== "ok") {
|
|
11664
|
+
const finishedPayload2 = {
|
|
11665
|
+
generation_batch_id: input.generationBatchId,
|
|
11666
|
+
status: "failed",
|
|
11667
|
+
produced_count: 0,
|
|
11668
|
+
diagnostic: persistiert.kind === "error" ? persistiert.message : `Batch ${input.generationBatchId} konnte nicht gespeichert werden (${persistiert.kind}).`,
|
|
11669
|
+
finished_at: now().toISOString()
|
|
11670
|
+
};
|
|
11671
|
+
await events.appendEvent(SZENEN_EVENT_TYPES.imageGenerationFinished, finishedPayload2).catch(() => {
|
|
11672
|
+
});
|
|
11673
|
+
return { kind: "failed", message: finishedPayload2.diagnostic };
|
|
11674
|
+
}
|
|
11675
|
+
const istPartial = produced.length < input.imageCount;
|
|
11676
|
+
const finishedPayload = {
|
|
11677
|
+
generation_batch_id: input.generationBatchId,
|
|
11678
|
+
status: istPartial ? "partial" : "succeeded",
|
|
11679
|
+
item_id: persistiert.value.item_id,
|
|
11680
|
+
produced_count: produced.length,
|
|
11681
|
+
finished_at: now().toISOString()
|
|
11682
|
+
};
|
|
11683
|
+
await events.appendEvent(SZENEN_EVENT_TYPES.imageGenerationFinished, finishedPayload).catch(() => {
|
|
11684
|
+
});
|
|
11685
|
+
return istPartial ? { kind: "partial", batch: persistiert.value, requested: input.imageCount, produced: produced.length } : { kind: "succeeded", batch: persistiert.value };
|
|
11686
|
+
}
|
|
11687
|
+
};
|
|
11688
|
+
}
|
|
11689
|
+
|
|
11141
11690
|
// src/lib/szenen/flowViewPort.ts
|
|
11142
11691
|
var defaultContext = {
|
|
11143
11692
|
async chainFor(contextId) {
|
|
@@ -11185,8 +11734,36 @@ function createFlowSzenenViewPort(options) {
|
|
|
11185
11734
|
...options.newRunId ? { newRunId: options.newRunId } : {},
|
|
11186
11735
|
...options.now ? { now: options.now } : {}
|
|
11187
11736
|
});
|
|
11188
|
-
const
|
|
11737
|
+
const imageBatchHistory = createHfImageBatchHistory({ channel });
|
|
11738
|
+
const hatHfZugangsdaten = Boolean(options.namespace?.trim() && options.token?.trim());
|
|
11739
|
+
const imageBatchWrite = hatHfZugangsdaten ? createHfImageBatchWrite({
|
|
11740
|
+
namespace: options.namespace,
|
|
11741
|
+
token: options.token,
|
|
11742
|
+
channel,
|
|
11743
|
+
...options.newBatchImageId ? { newImageId: options.newBatchImageId } : {},
|
|
11744
|
+
...options.now ? { now: options.now } : {}
|
|
11745
|
+
}) : void 0;
|
|
11746
|
+
const bildProvider = options.imageProvider ?? (options.generateImage ? createFlowImageProvider(options.generateImage) : void 0);
|
|
11747
|
+
const imageGeneration = bildProvider && imageBatchWrite ? createImageGenerationPort({
|
|
11748
|
+
runs: { async getRun(runId) {
|
|
11749
|
+
return runs.getRun(runId);
|
|
11750
|
+
} },
|
|
11751
|
+
provider: bildProvider,
|
|
11752
|
+
batches: createHfImageGenerationBatchPersistence({
|
|
11753
|
+
namespace: options.namespace,
|
|
11754
|
+
token: options.token,
|
|
11755
|
+
channel,
|
|
11756
|
+
...options.newBatchImageId ? { newImageId: options.newBatchImageId } : {},
|
|
11757
|
+
...options.now ? { now: options.now } : {}
|
|
11758
|
+
}),
|
|
11759
|
+
events: channel,
|
|
11760
|
+
hasAccess: options.imageProviderHasAccess ?? flowImageProviderHasAccess,
|
|
11761
|
+
...options.now ? { now: options.now } : {}
|
|
11762
|
+
}) : void 0;
|
|
11763
|
+
const port = { elements, context, runs, derivation, imageBatchHistory };
|
|
11189
11764
|
if (imageLibrary) port.imageLibrary = imageLibrary;
|
|
11765
|
+
if (imageBatchWrite) port.imageBatchWrite = imageBatchWrite;
|
|
11766
|
+
if (imageGeneration) port.imageGeneration = imageGeneration;
|
|
11190
11767
|
return port;
|
|
11191
11768
|
}
|
|
11192
11769
|
|
|
@@ -11306,5 +11883,20 @@ export {
|
|
|
11306
11883
|
createEventLogRunPersistence,
|
|
11307
11884
|
createClientRunPort,
|
|
11308
11885
|
createHfImageLibrary,
|
|
11886
|
+
FLOW_MODEL_DISPLAY_NAMES,
|
|
11887
|
+
flowImageProviderHasAccess,
|
|
11888
|
+
createFlowImageProvider,
|
|
11889
|
+
collectImageGenerationOrders,
|
|
11890
|
+
ordersForPromptRun,
|
|
11891
|
+
findImageGenerationOrder,
|
|
11892
|
+
collectImageBatches,
|
|
11893
|
+
batchesForPromptRun,
|
|
11894
|
+
findImageBatch,
|
|
11895
|
+
createHfImageBatchHistory,
|
|
11896
|
+
createHfImageGenerationBatchPersistence,
|
|
11897
|
+
createHfImageBatchWrite,
|
|
11898
|
+
callableImageModelFor,
|
|
11899
|
+
capabilityForTargetModel,
|
|
11900
|
+
createImageGenerationPort,
|
|
11309
11901
|
createFlowSzenenViewPort
|
|
11310
11902
|
};
|
package/dist/index.d.mts
CHANGED
|
@@ -6,7 +6,7 @@ import { Node, Edge } from '@xyflow/react';
|
|
|
6
6
|
import * as zustand_vanilla from 'zustand/vanilla';
|
|
7
7
|
import { F as FeatureSliceId, b as SliceContract, a as PersistenceDescriptor, W as WorkspacePersistence, P as PersistedSlice, L as LoadResult, f as WriteResult, e as WorkspaceTabId, C as CommandResult, R as RequestContext, Q as QueryResult } from './contracts-DdYOMBl9.mjs';
|
|
8
8
|
|
|
9
|
-
var version = "2.0.
|
|
9
|
+
var version = "2.0.83";
|
|
10
10
|
|
|
11
11
|
declare function useOnClickOutside(ref: RefObject<HTMLElement | null>, handler: (e: MouseEvent | TouchEvent) => void): void;
|
|
12
12
|
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { Node, Edge } from '@xyflow/react';
|
|
|
6
6
|
import * as zustand_vanilla from 'zustand/vanilla';
|
|
7
7
|
import { F as FeatureSliceId, b as SliceContract, a as PersistenceDescriptor, W as WorkspacePersistence, P as PersistedSlice, L as LoadResult, f as WriteResult, e as WorkspaceTabId, C as CommandResult, R as RequestContext, Q as QueryResult } from './contracts-DdYOMBl9.js';
|
|
8
8
|
|
|
9
|
-
var version = "2.0.
|
|
9
|
+
var version = "2.0.83";
|
|
10
10
|
|
|
11
11
|
declare function useOnClickOutside(ref: RefObject<HTMLElement | null>, handler: (e: MouseEvent | TouchEvent) => void): void;
|
|
12
12
|
|