@rslsp1/fa-app-tools 2.0.83 → 2.0.85
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-VBWQP7PO.mjs → chunk-LFPOXNOZ.mjs} +18 -3
- package/dist/{chunk-JTGC5PXJ.mjs → chunk-MILMVOK7.mjs} +50 -18
- package/dist/{hfStateService-WKQLNDHO.mjs → hfStateService-PZH2IDKF.mjs} +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +69 -22
- package/dist/index.mjs +5 -5
- package/dist/szenen.d.mts +13 -3
- package/dist/szenen.d.ts +13 -3
- package/dist/szenen.js +67 -20
- package/dist/szenen.mjs +2 -2
- package/package.json +1 -1
|
@@ -15,6 +15,21 @@ function treeUrl(namespace, subdir = "") {
|
|
|
15
15
|
var DROSSEL_VERSUCHE = 4;
|
|
16
16
|
var DROSSEL_BASIS_MS = 400;
|
|
17
17
|
var schlafen = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
18
|
+
var HF_LESE_ZEITLIMIT_MS = 2e4;
|
|
19
|
+
async function holeMitZeitlimit(url, init) {
|
|
20
|
+
const abbruch = new AbortController();
|
|
21
|
+
const timer = setTimeout(() => abbruch.abort(), HF_LESE_ZEITLIMIT_MS);
|
|
22
|
+
try {
|
|
23
|
+
return await fetch(url, { ...init, signal: abbruch.signal });
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (abbruch.signal.aborted) {
|
|
26
|
+
throw new Error(`HF-Anfrage ohne Antwort nach ${HF_LESE_ZEITLIMIT_MS}ms abgebrochen: ${url}`);
|
|
27
|
+
}
|
|
28
|
+
throw error;
|
|
29
|
+
} finally {
|
|
30
|
+
clearTimeout(timer);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
18
33
|
async function mitGeduld(anfrage) {
|
|
19
34
|
let letzte = null;
|
|
20
35
|
for (let versuch = 0; versuch < DROSSEL_VERSUCHE; versuch += 1) {
|
|
@@ -29,7 +44,7 @@ async function mitGeduld(anfrage) {
|
|
|
29
44
|
return letzte;
|
|
30
45
|
}
|
|
31
46
|
async function hfListDir(namespace, subdir, token) {
|
|
32
|
-
const res = await mitGeduld(() =>
|
|
47
|
+
const res = await mitGeduld(() => holeMitZeitlimit(treeUrl(namespace, subdir), {
|
|
33
48
|
headers: { Authorization: `Bearer ${token}` }
|
|
34
49
|
}));
|
|
35
50
|
if (res.status === 404) return [];
|
|
@@ -37,7 +52,7 @@ async function hfListDir(namespace, subdir, token) {
|
|
|
37
52
|
return res.json();
|
|
38
53
|
}
|
|
39
54
|
async function hfDownloadJsonByPath(repoPath, token) {
|
|
40
|
-
const res = await mitGeduld(() =>
|
|
55
|
+
const res = await mitGeduld(() => holeMitZeitlimit(
|
|
41
56
|
`${HF_BASE}/datasets/${HF_REPO}/resolve/main/${repoPath}?download=true`,
|
|
42
57
|
{ headers: { Authorization: `Bearer ${token}` } }
|
|
43
58
|
));
|
|
@@ -45,7 +60,7 @@ async function hfDownloadJsonByPath(repoPath, token) {
|
|
|
45
60
|
return res.json();
|
|
46
61
|
}
|
|
47
62
|
async function hfDownloadBinaryByPath(repoPath, token) {
|
|
48
|
-
const res = await mitGeduld(() =>
|
|
63
|
+
const res = await mitGeduld(() => holeMitZeitlimit(
|
|
49
64
|
`${HF_BASE}/datasets/${HF_REPO}/resolve/main/${repoPath}?download=true`,
|
|
50
65
|
{ headers: { Authorization: `Bearer ${token}` } }
|
|
51
66
|
));
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
loadHFState,
|
|
11
11
|
loadPendingEvents,
|
|
12
12
|
writeHFEvent
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-LFPOXNOZ.mjs";
|
|
14
14
|
|
|
15
15
|
// src/lib/szenen/viewPort.ts
|
|
16
16
|
function capabilitiesOf(port) {
|
|
@@ -11109,25 +11109,29 @@ function createHfImageLibrary(options) {
|
|
|
11109
11109
|
try {
|
|
11110
11110
|
const zustand = await loadHFState(namespace, token);
|
|
11111
11111
|
const eintrag = (zustand?.metadata ?? []).find((e) => e.id === mediaRef);
|
|
11112
|
-
if (
|
|
11113
|
-
|
|
11114
|
-
|
|
11115
|
-
|
|
11112
|
+
if (eintrag) {
|
|
11113
|
+
const base64 = await hfLoadImageAsBase64(
|
|
11114
|
+
mediaRef,
|
|
11115
|
+
token,
|
|
11116
|
+
void 0,
|
|
11117
|
+
eintrag.filename,
|
|
11118
|
+
void 0,
|
|
11119
|
+
eintrag.mimeType,
|
|
11120
|
+
false
|
|
11116
11121
|
);
|
|
11122
|
+
if (!base64) {
|
|
11123
|
+
return fehler2(`Das Bild ${mediaRef} ist im Bestand verzeichnet, aber nicht ladbar.`, true);
|
|
11124
|
+
}
|
|
11125
|
+
return { kind: "ok", value: { data: base64, mime_type: eintrag.mimeType || "image/jpeg" } };
|
|
11117
11126
|
}
|
|
11118
|
-
const
|
|
11119
|
-
mediaRef,
|
|
11120
|
-
|
|
11121
|
-
void 0,
|
|
11122
|
-
eintrag.filename,
|
|
11123
|
-
void 0,
|
|
11124
|
-
eintrag.mimeType,
|
|
11125
|
-
false
|
|
11126
|
-
);
|
|
11127
|
-
if (!base64) {
|
|
11128
|
-
return fehler2(`Das Bild ${mediaRef} ist im Bestand verzeichnet, aber nicht ladbar.`, true);
|
|
11127
|
+
for (const mimeType of ["image/png", "image/jpeg"]) {
|
|
11128
|
+
const base64 = await hfLoadImageAsBase64(mediaRef, token, void 0, void 0, void 0, mimeType, false);
|
|
11129
|
+
if (base64) return { kind: "ok", value: { data: base64, mime_type: mimeType } };
|
|
11129
11130
|
}
|
|
11130
|
-
return
|
|
11131
|
+
return fehler2(
|
|
11132
|
+
`Das Bild ${mediaRef} steht nicht im Bestand. Moeglicherweise hat der Abgleich es noch nicht uebertragen.`,
|
|
11133
|
+
true
|
|
11134
|
+
);
|
|
11131
11135
|
} catch (error) {
|
|
11132
11136
|
return fehler2(
|
|
11133
11137
|
`Das Bild ${mediaRef} konnte nicht geladen werden: ${error instanceof Error ? error.message : String(error)}`,
|
|
@@ -11163,7 +11167,9 @@ function createHfImageLibrary(options) {
|
|
|
11163
11167
|
|
|
11164
11168
|
// src/lib/szenen/flowImageProvider.ts
|
|
11165
11169
|
var FLOW_MODEL_DISPLAY_NAMES = {
|
|
11166
|
-
"imagen-4.0-generate-001": "Imagen 4"
|
|
11170
|
+
"imagen-4.0-generate-001": "Imagen 4",
|
|
11171
|
+
"flow-nano-banana-pro": "\u{1F34C} Nano Banana Pro",
|
|
11172
|
+
"flow-nano-banana-2": "\u{1F34C} Nano Banana 2"
|
|
11167
11173
|
};
|
|
11168
11174
|
function flowImageProviderHasAccess(model) {
|
|
11169
11175
|
return model.callable_model_id in FLOW_MODEL_DISPLAY_NAMES;
|
|
@@ -11514,6 +11520,32 @@ var IMAGE_MODEL_CATALOGUE = {
|
|
|
11514
11520
|
max_images: 4,
|
|
11515
11521
|
aspect_ratios: ["1:1", "3:4", "4:3", "9:16", "16:9"],
|
|
11516
11522
|
supports_seed: true
|
|
11523
|
+
},
|
|
11524
|
+
/**
|
|
11525
|
+
* Stufe 6.9.2, Nachtrag — real gegen Flow geprüft (2026-08-17): Der
|
|
11526
|
+
* Modellwähler im Flow-„Generieren"-Tab zeigt aktuell nur "Nano Banana Pro"
|
|
11527
|
+
* und "Nano Banana 2" als wählbar an, "Imagen 4" erscheint dort ausgegraut.
|
|
11528
|
+
* `provider: 'flow'` statt `'google'` ist bewusst: Diese Modelle sind nur
|
|
11529
|
+
* über `Flow.generate.image` erreichbar, nicht über die direkte
|
|
11530
|
+
* Google-Imagen-REST-Route, die der React-Host benutzt (`reactImageProvider.ts`)
|
|
11531
|
+
* — React meldet sie deshalb korrekt als `unsupported`, ohne eine eigene
|
|
11532
|
+
* Host-Verzweigung zu brauchen (D-115/R-1: `hasAccess` prüft `provider`).
|
|
11533
|
+
*/
|
|
11534
|
+
nano_banana_pro: {
|
|
11535
|
+
callable_model_id: "flow-nano-banana-pro",
|
|
11536
|
+
provider: "flow",
|
|
11537
|
+
max_images: 4,
|
|
11538
|
+
// Flow.generate.image dokumentiert nur '1:1' | '16:9' | '9:16' (howto-flow-sdk.md).
|
|
11539
|
+
aspect_ratios: ["1:1", "16:9", "9:16"],
|
|
11540
|
+
// Weder als Eingabe- noch als Ausgabeparameter dokumentiert — nichts erfunden (D-107).
|
|
11541
|
+
supports_seed: false
|
|
11542
|
+
},
|
|
11543
|
+
nano_banana_2: {
|
|
11544
|
+
callable_model_id: "flow-nano-banana-2",
|
|
11545
|
+
provider: "flow",
|
|
11546
|
+
max_images: 4,
|
|
11547
|
+
aspect_ratios: ["1:1", "16:9", "9:16"],
|
|
11548
|
+
supports_seed: false
|
|
11517
11549
|
}
|
|
11518
11550
|
};
|
|
11519
11551
|
function callableImageModelFor(targetModelKey) {
|
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.85";
|
|
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.85";
|
|
10
10
|
|
|
11
11
|
declare function useOnClickOutside(ref: RefObject<HTMLElement | null>, handler: (e: MouseEvent | TouchEvent) => void): void;
|
|
12
12
|
|
package/dist/index.js
CHANGED
|
@@ -275,6 +275,20 @@ function treeUrl(namespace, subdir = "") {
|
|
|
275
275
|
const parts = [namespace.replace(/\/$/, ""), subdir].filter(Boolean).join("/");
|
|
276
276
|
return `${HF_BASE}/api/datasets/${HF_REPO}/tree/main${parts ? "/" + parts : ""}`;
|
|
277
277
|
}
|
|
278
|
+
async function holeMitZeitlimit(url, init) {
|
|
279
|
+
const abbruch = new AbortController();
|
|
280
|
+
const timer = setTimeout(() => abbruch.abort(), HF_LESE_ZEITLIMIT_MS);
|
|
281
|
+
try {
|
|
282
|
+
return await fetch(url, { ...init, signal: abbruch.signal });
|
|
283
|
+
} catch (error) {
|
|
284
|
+
if (abbruch.signal.aborted) {
|
|
285
|
+
throw new Error(`HF-Anfrage ohne Antwort nach ${HF_LESE_ZEITLIMIT_MS}ms abgebrochen: ${url}`);
|
|
286
|
+
}
|
|
287
|
+
throw error;
|
|
288
|
+
} finally {
|
|
289
|
+
clearTimeout(timer);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
278
292
|
async function mitGeduld(anfrage) {
|
|
279
293
|
let letzte = null;
|
|
280
294
|
for (let versuch = 0; versuch < DROSSEL_VERSUCHE; versuch += 1) {
|
|
@@ -289,7 +303,7 @@ async function mitGeduld(anfrage) {
|
|
|
289
303
|
return letzte;
|
|
290
304
|
}
|
|
291
305
|
async function hfListDir(namespace, subdir, token) {
|
|
292
|
-
const res = await mitGeduld(() =>
|
|
306
|
+
const res = await mitGeduld(() => holeMitZeitlimit(treeUrl(namespace, subdir), {
|
|
293
307
|
headers: { Authorization: `Bearer ${token}` }
|
|
294
308
|
}));
|
|
295
309
|
if (res.status === 404) return [];
|
|
@@ -297,7 +311,7 @@ async function hfListDir(namespace, subdir, token) {
|
|
|
297
311
|
return res.json();
|
|
298
312
|
}
|
|
299
313
|
async function hfDownloadJsonByPath(repoPath, token) {
|
|
300
|
-
const res = await mitGeduld(() =>
|
|
314
|
+
const res = await mitGeduld(() => holeMitZeitlimit(
|
|
301
315
|
`${HF_BASE}/datasets/${HF_REPO}/resolve/main/${repoPath}?download=true`,
|
|
302
316
|
{ headers: { Authorization: `Bearer ${token}` } }
|
|
303
317
|
));
|
|
@@ -305,7 +319,7 @@ async function hfDownloadJsonByPath(repoPath, token) {
|
|
|
305
319
|
return res.json();
|
|
306
320
|
}
|
|
307
321
|
async function hfDownloadBinaryByPath(repoPath, token) {
|
|
308
|
-
const res = await mitGeduld(() =>
|
|
322
|
+
const res = await mitGeduld(() => holeMitZeitlimit(
|
|
309
323
|
`${HF_BASE}/datasets/${HF_REPO}/resolve/main/${repoPath}?download=true`,
|
|
310
324
|
{ headers: { Authorization: `Bearer ${token}` } }
|
|
311
325
|
));
|
|
@@ -417,7 +431,7 @@ async function writeHFEvent(namespace, token, type, payload, prevTs, options) {
|
|
|
417
431
|
await hfUploadSmallFile(repoPath, JSON.stringify(event, null, 2), token, `Event: ${type}`);
|
|
418
432
|
return event;
|
|
419
433
|
}
|
|
420
|
-
var DROSSEL_VERSUCHE, DROSSEL_BASIS_MS, schlafen, EVENTDOWNLOAD_PARALLELITAET, SESSION_CLIENT_ID, writeSeq, lastOrderedTs;
|
|
434
|
+
var DROSSEL_VERSUCHE, DROSSEL_BASIS_MS, schlafen, HF_LESE_ZEITLIMIT_MS, EVENTDOWNLOAD_PARALLELITAET, SESSION_CLIENT_ID, writeSeq, lastOrderedTs;
|
|
421
435
|
var init_hfEventLog = __esm({
|
|
422
436
|
"src/lib/hfEventLog.ts"() {
|
|
423
437
|
"use strict";
|
|
@@ -425,6 +439,7 @@ var init_hfEventLog = __esm({
|
|
|
425
439
|
DROSSEL_VERSUCHE = 4;
|
|
426
440
|
DROSSEL_BASIS_MS = 400;
|
|
427
441
|
schlafen = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
442
|
+
HF_LESE_ZEITLIMIT_MS = 2e4;
|
|
428
443
|
EVENTDOWNLOAD_PARALLELITAET = 3;
|
|
429
444
|
SESSION_CLIENT_ID = `client-${crypto.randomUUID().slice(0, 8)}`;
|
|
430
445
|
writeSeq = 0;
|
|
@@ -786,7 +801,7 @@ __export(index_exports, {
|
|
|
786
801
|
module.exports = __toCommonJS(index_exports);
|
|
787
802
|
|
|
788
803
|
// package.json
|
|
789
|
-
var version = "2.0.
|
|
804
|
+
var version = "2.0.85";
|
|
790
805
|
|
|
791
806
|
// src/hooks/useOnClickOutside.ts
|
|
792
807
|
var import_react = require("react");
|
|
@@ -17467,25 +17482,29 @@ function createHfImageLibrary(options) {
|
|
|
17467
17482
|
try {
|
|
17468
17483
|
const zustand = await loadHFState(namespace, token);
|
|
17469
17484
|
const eintrag = (zustand?.metadata ?? []).find((e) => e.id === mediaRef);
|
|
17470
|
-
if (
|
|
17471
|
-
|
|
17472
|
-
|
|
17473
|
-
|
|
17485
|
+
if (eintrag) {
|
|
17486
|
+
const base64 = await hfLoadImageAsBase64(
|
|
17487
|
+
mediaRef,
|
|
17488
|
+
token,
|
|
17489
|
+
void 0,
|
|
17490
|
+
eintrag.filename,
|
|
17491
|
+
void 0,
|
|
17492
|
+
eintrag.mimeType,
|
|
17493
|
+
false
|
|
17474
17494
|
);
|
|
17495
|
+
if (!base64) {
|
|
17496
|
+
return fehler2(`Das Bild ${mediaRef} ist im Bestand verzeichnet, aber nicht ladbar.`, true);
|
|
17497
|
+
}
|
|
17498
|
+
return { kind: "ok", value: { data: base64, mime_type: eintrag.mimeType || "image/jpeg" } };
|
|
17475
17499
|
}
|
|
17476
|
-
const
|
|
17477
|
-
mediaRef,
|
|
17478
|
-
|
|
17479
|
-
void 0,
|
|
17480
|
-
eintrag.filename,
|
|
17481
|
-
void 0,
|
|
17482
|
-
eintrag.mimeType,
|
|
17483
|
-
false
|
|
17484
|
-
);
|
|
17485
|
-
if (!base64) {
|
|
17486
|
-
return fehler2(`Das Bild ${mediaRef} ist im Bestand verzeichnet, aber nicht ladbar.`, true);
|
|
17500
|
+
for (const mimeType of ["image/png", "image/jpeg"]) {
|
|
17501
|
+
const base64 = await hfLoadImageAsBase64(mediaRef, token, void 0, void 0, void 0, mimeType, false);
|
|
17502
|
+
if (base64) return { kind: "ok", value: { data: base64, mime_type: mimeType } };
|
|
17487
17503
|
}
|
|
17488
|
-
return
|
|
17504
|
+
return fehler2(
|
|
17505
|
+
`Das Bild ${mediaRef} steht nicht im Bestand. Moeglicherweise hat der Abgleich es noch nicht uebertragen.`,
|
|
17506
|
+
true
|
|
17507
|
+
);
|
|
17489
17508
|
} catch (error) {
|
|
17490
17509
|
return fehler2(
|
|
17491
17510
|
`Das Bild ${mediaRef} konnte nicht geladen werden: ${error instanceof Error ? error.message : String(error)}`,
|
|
@@ -17521,7 +17540,9 @@ function createHfImageLibrary(options) {
|
|
|
17521
17540
|
|
|
17522
17541
|
// src/lib/szenen/flowImageProvider.ts
|
|
17523
17542
|
var FLOW_MODEL_DISPLAY_NAMES = {
|
|
17524
|
-
"imagen-4.0-generate-001": "Imagen 4"
|
|
17543
|
+
"imagen-4.0-generate-001": "Imagen 4",
|
|
17544
|
+
"flow-nano-banana-pro": "\u{1F34C} Nano Banana Pro",
|
|
17545
|
+
"flow-nano-banana-2": "\u{1F34C} Nano Banana 2"
|
|
17525
17546
|
};
|
|
17526
17547
|
function flowImageProviderHasAccess(model) {
|
|
17527
17548
|
return model.callable_model_id in FLOW_MODEL_DISPLAY_NAMES;
|
|
@@ -17871,6 +17892,32 @@ var IMAGE_MODEL_CATALOGUE = {
|
|
|
17871
17892
|
max_images: 4,
|
|
17872
17893
|
aspect_ratios: ["1:1", "3:4", "4:3", "9:16", "16:9"],
|
|
17873
17894
|
supports_seed: true
|
|
17895
|
+
},
|
|
17896
|
+
/**
|
|
17897
|
+
* Stufe 6.9.2, Nachtrag — real gegen Flow geprüft (2026-08-17): Der
|
|
17898
|
+
* Modellwähler im Flow-„Generieren"-Tab zeigt aktuell nur "Nano Banana Pro"
|
|
17899
|
+
* und "Nano Banana 2" als wählbar an, "Imagen 4" erscheint dort ausgegraut.
|
|
17900
|
+
* `provider: 'flow'` statt `'google'` ist bewusst: Diese Modelle sind nur
|
|
17901
|
+
* über `Flow.generate.image` erreichbar, nicht über die direkte
|
|
17902
|
+
* Google-Imagen-REST-Route, die der React-Host benutzt (`reactImageProvider.ts`)
|
|
17903
|
+
* — React meldet sie deshalb korrekt als `unsupported`, ohne eine eigene
|
|
17904
|
+
* Host-Verzweigung zu brauchen (D-115/R-1: `hasAccess` prüft `provider`).
|
|
17905
|
+
*/
|
|
17906
|
+
nano_banana_pro: {
|
|
17907
|
+
callable_model_id: "flow-nano-banana-pro",
|
|
17908
|
+
provider: "flow",
|
|
17909
|
+
max_images: 4,
|
|
17910
|
+
// Flow.generate.image dokumentiert nur '1:1' | '16:9' | '9:16' (howto-flow-sdk.md).
|
|
17911
|
+
aspect_ratios: ["1:1", "16:9", "9:16"],
|
|
17912
|
+
// Weder als Eingabe- noch als Ausgabeparameter dokumentiert — nichts erfunden (D-107).
|
|
17913
|
+
supports_seed: false
|
|
17914
|
+
},
|
|
17915
|
+
nano_banana_2: {
|
|
17916
|
+
callable_model_id: "flow-nano-banana-2",
|
|
17917
|
+
provider: "flow",
|
|
17918
|
+
max_images: 4,
|
|
17919
|
+
aspect_ratios: ["1:1", "16:9", "9:16"],
|
|
17920
|
+
supports_seed: false
|
|
17874
17921
|
}
|
|
17875
17922
|
};
|
|
17876
17923
|
function callableImageModelFor(targetModelKey) {
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SzenenView,
|
|
3
3
|
createFlowSzenenViewPort
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MILMVOK7.mjs";
|
|
5
5
|
import "./chunk-FUY2OCVC.mjs";
|
|
6
6
|
import {
|
|
7
7
|
exportProjectToZip,
|
|
@@ -27,10 +27,10 @@ import {
|
|
|
27
27
|
setHFToken,
|
|
28
28
|
tsFromEventPath,
|
|
29
29
|
writeHFEvent
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-LFPOXNOZ.mjs";
|
|
31
31
|
|
|
32
32
|
// package.json
|
|
33
|
-
var version = "2.0.
|
|
33
|
+
var version = "2.0.85";
|
|
34
34
|
|
|
35
35
|
// src/hooks/useOnClickOutside.ts
|
|
36
36
|
import { useEffect } from "react";
|
|
@@ -2308,7 +2308,7 @@ var ProjectSyncTab = ({
|
|
|
2308
2308
|
{
|
|
2309
2309
|
onClick: async () => {
|
|
2310
2310
|
try {
|
|
2311
|
-
const { hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-
|
|
2311
|
+
const { hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-PZH2IDKF.mjs");
|
|
2312
2312
|
const file = await hfDownloadProject2(p.path, hfToken);
|
|
2313
2313
|
onHfLoad(file);
|
|
2314
2314
|
} catch (e) {
|
|
@@ -6856,7 +6856,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6856
6856
|
onClick: async () => {
|
|
6857
6857
|
setIsLoadingFromHF(true);
|
|
6858
6858
|
try {
|
|
6859
|
-
const { hfListProjects: hfListProjects2, hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-
|
|
6859
|
+
const { hfListProjects: hfListProjects2, hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-PZH2IDKF.mjs");
|
|
6860
6860
|
const projects = await hfListProjects2(hfToken);
|
|
6861
6861
|
if (projects.length > 0) {
|
|
6862
6862
|
const file = await hfDownloadProject2(projects[0].path, hfToken);
|
package/dist/szenen.d.mts
CHANGED
|
@@ -2488,9 +2488,19 @@ type FlowGenerateImage = (params: FlowGenerateImageParams) => Promise<{
|
|
|
2488
2488
|
* Flow-Display-Namen (`howto-flow-sdk.md` — bekannt sind "🍌 Nano Banana Pro",
|
|
2489
2489
|
* "🍌 Nano Banana 2", "Imagen 4").
|
|
2490
2490
|
*
|
|
2491
|
-
*
|
|
2492
|
-
* `
|
|
2493
|
-
*
|
|
2491
|
+
* Der genaue String für "Nano Banana Pro" ist real belegt, nicht nur
|
|
2492
|
+
* dokumentiert: `AvatarArchitectApp.tsx`s produktive Labs-Generierung
|
|
2493
|
+
* verwendet `'🍌 Nano Banana Pro'` als Vorgabewert und reicht ihn
|
|
2494
|
+
* unverändert als `modelDisplayName` an `Flow.generate.image()` durch
|
|
2495
|
+
* (`aiHelpers.ts#buildImageGenerationOptions`).
|
|
2496
|
+
*
|
|
2497
|
+
* "Imagen 4" bleibt katalogisiert, obwohl es im Modellwähler des
|
|
2498
|
+
* Flow-„Generieren"-Tabs am 2026-08-17 ausgegraut erschien (Screenshot,
|
|
2499
|
+
* nur "Nano Banana Pro"/"Nano Banana 2" wählbar) — das kann kontoabhängig
|
|
2500
|
+
* sein. Ein Aufruf schlägt dann mit der echten Flow-Fehlermeldung fehl,
|
|
2501
|
+
* statt einen stillen Fallback zu erzeugen (D-6.9.2-3).
|
|
2502
|
+
* `imagen-3.0-generate-001` bleibt bewusst draußen: Dafür ist kein
|
|
2503
|
+
* Flow-Display-Name dokumentiert oder belegt.
|
|
2494
2504
|
*/
|
|
2495
2505
|
declare const FLOW_MODEL_DISPLAY_NAMES: Readonly<Record<string, string>>;
|
|
2496
2506
|
/**
|
package/dist/szenen.d.ts
CHANGED
|
@@ -2488,9 +2488,19 @@ type FlowGenerateImage = (params: FlowGenerateImageParams) => Promise<{
|
|
|
2488
2488
|
* Flow-Display-Namen (`howto-flow-sdk.md` — bekannt sind "🍌 Nano Banana Pro",
|
|
2489
2489
|
* "🍌 Nano Banana 2", "Imagen 4").
|
|
2490
2490
|
*
|
|
2491
|
-
*
|
|
2492
|
-
* `
|
|
2493
|
-
*
|
|
2491
|
+
* Der genaue String für "Nano Banana Pro" ist real belegt, nicht nur
|
|
2492
|
+
* dokumentiert: `AvatarArchitectApp.tsx`s produktive Labs-Generierung
|
|
2493
|
+
* verwendet `'🍌 Nano Banana Pro'` als Vorgabewert und reicht ihn
|
|
2494
|
+
* unverändert als `modelDisplayName` an `Flow.generate.image()` durch
|
|
2495
|
+
* (`aiHelpers.ts#buildImageGenerationOptions`).
|
|
2496
|
+
*
|
|
2497
|
+
* "Imagen 4" bleibt katalogisiert, obwohl es im Modellwähler des
|
|
2498
|
+
* Flow-„Generieren"-Tabs am 2026-08-17 ausgegraut erschien (Screenshot,
|
|
2499
|
+
* nur "Nano Banana Pro"/"Nano Banana 2" wählbar) — das kann kontoabhängig
|
|
2500
|
+
* sein. Ein Aufruf schlägt dann mit der echten Flow-Fehlermeldung fehl,
|
|
2501
|
+
* statt einen stillen Fallback zu erzeugen (D-6.9.2-3).
|
|
2502
|
+
* `imagen-3.0-generate-001` bleibt bewusst draußen: Dafür ist kein
|
|
2503
|
+
* Flow-Display-Name dokumentiert oder belegt.
|
|
2494
2504
|
*/
|
|
2495
2505
|
declare const FLOW_MODEL_DISPLAY_NAMES: Readonly<Record<string, string>>;
|
|
2496
2506
|
/**
|
package/dist/szenen.js
CHANGED
|
@@ -7572,6 +7572,21 @@ function treeUrl(namespace, subdir = "") {
|
|
|
7572
7572
|
var DROSSEL_VERSUCHE = 4;
|
|
7573
7573
|
var DROSSEL_BASIS_MS = 400;
|
|
7574
7574
|
var schlafen = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
7575
|
+
var HF_LESE_ZEITLIMIT_MS = 2e4;
|
|
7576
|
+
async function holeMitZeitlimit(url, init) {
|
|
7577
|
+
const abbruch = new AbortController();
|
|
7578
|
+
const timer = setTimeout(() => abbruch.abort(), HF_LESE_ZEITLIMIT_MS);
|
|
7579
|
+
try {
|
|
7580
|
+
return await fetch(url, { ...init, signal: abbruch.signal });
|
|
7581
|
+
} catch (error) {
|
|
7582
|
+
if (abbruch.signal.aborted) {
|
|
7583
|
+
throw new Error(`HF-Anfrage ohne Antwort nach ${HF_LESE_ZEITLIMIT_MS}ms abgebrochen: ${url}`);
|
|
7584
|
+
}
|
|
7585
|
+
throw error;
|
|
7586
|
+
} finally {
|
|
7587
|
+
clearTimeout(timer);
|
|
7588
|
+
}
|
|
7589
|
+
}
|
|
7575
7590
|
async function mitGeduld(anfrage) {
|
|
7576
7591
|
let letzte = null;
|
|
7577
7592
|
for (let versuch = 0; versuch < DROSSEL_VERSUCHE; versuch += 1) {
|
|
@@ -7586,7 +7601,7 @@ async function mitGeduld(anfrage) {
|
|
|
7586
7601
|
return letzte;
|
|
7587
7602
|
}
|
|
7588
7603
|
async function hfListDir(namespace, subdir, token) {
|
|
7589
|
-
const res = await mitGeduld(() =>
|
|
7604
|
+
const res = await mitGeduld(() => holeMitZeitlimit(treeUrl(namespace, subdir), {
|
|
7590
7605
|
headers: { Authorization: `Bearer ${token}` }
|
|
7591
7606
|
}));
|
|
7592
7607
|
if (res.status === 404) return [];
|
|
@@ -7594,7 +7609,7 @@ async function hfListDir(namespace, subdir, token) {
|
|
|
7594
7609
|
return res.json();
|
|
7595
7610
|
}
|
|
7596
7611
|
async function hfDownloadJsonByPath(repoPath, token) {
|
|
7597
|
-
const res = await mitGeduld(() =>
|
|
7612
|
+
const res = await mitGeduld(() => holeMitZeitlimit(
|
|
7598
7613
|
`${HF_BASE}/datasets/${HF_REPO}/resolve/main/${repoPath}?download=true`,
|
|
7599
7614
|
{ headers: { Authorization: `Bearer ${token}` } }
|
|
7600
7615
|
));
|
|
@@ -7602,7 +7617,7 @@ async function hfDownloadJsonByPath(repoPath, token) {
|
|
|
7602
7617
|
return res.json();
|
|
7603
7618
|
}
|
|
7604
7619
|
async function hfDownloadBinaryByPath(repoPath, token) {
|
|
7605
|
-
const res = await mitGeduld(() =>
|
|
7620
|
+
const res = await mitGeduld(() => holeMitZeitlimit(
|
|
7606
7621
|
`${HF_BASE}/datasets/${HF_REPO}/resolve/main/${repoPath}?download=true`,
|
|
7607
7622
|
{ headers: { Authorization: `Bearer ${token}` } }
|
|
7608
7623
|
));
|
|
@@ -9379,25 +9394,29 @@ function createHfImageLibrary(options) {
|
|
|
9379
9394
|
try {
|
|
9380
9395
|
const zustand = await loadHFState(namespace, token);
|
|
9381
9396
|
const eintrag = (zustand?.metadata ?? []).find((e) => e.id === mediaRef);
|
|
9382
|
-
if (
|
|
9383
|
-
|
|
9384
|
-
|
|
9385
|
-
|
|
9397
|
+
if (eintrag) {
|
|
9398
|
+
const base64 = await hfLoadImageAsBase64(
|
|
9399
|
+
mediaRef,
|
|
9400
|
+
token,
|
|
9401
|
+
void 0,
|
|
9402
|
+
eintrag.filename,
|
|
9403
|
+
void 0,
|
|
9404
|
+
eintrag.mimeType,
|
|
9405
|
+
false
|
|
9386
9406
|
);
|
|
9407
|
+
if (!base64) {
|
|
9408
|
+
return fehler(`Das Bild ${mediaRef} ist im Bestand verzeichnet, aber nicht ladbar.`, true);
|
|
9409
|
+
}
|
|
9410
|
+
return { kind: "ok", value: { data: base64, mime_type: eintrag.mimeType || "image/jpeg" } };
|
|
9387
9411
|
}
|
|
9388
|
-
const
|
|
9389
|
-
mediaRef,
|
|
9390
|
-
|
|
9391
|
-
void 0,
|
|
9392
|
-
eintrag.filename,
|
|
9393
|
-
void 0,
|
|
9394
|
-
eintrag.mimeType,
|
|
9395
|
-
false
|
|
9396
|
-
);
|
|
9397
|
-
if (!base64) {
|
|
9398
|
-
return fehler(`Das Bild ${mediaRef} ist im Bestand verzeichnet, aber nicht ladbar.`, true);
|
|
9412
|
+
for (const mimeType of ["image/png", "image/jpeg"]) {
|
|
9413
|
+
const base64 = await hfLoadImageAsBase64(mediaRef, token, void 0, void 0, void 0, mimeType, false);
|
|
9414
|
+
if (base64) return { kind: "ok", value: { data: base64, mime_type: mimeType } };
|
|
9399
9415
|
}
|
|
9400
|
-
return
|
|
9416
|
+
return fehler(
|
|
9417
|
+
`Das Bild ${mediaRef} steht nicht im Bestand. Moeglicherweise hat der Abgleich es noch nicht uebertragen.`,
|
|
9418
|
+
true
|
|
9419
|
+
);
|
|
9401
9420
|
} catch (error) {
|
|
9402
9421
|
return fehler(
|
|
9403
9422
|
`Das Bild ${mediaRef} konnte nicht geladen werden: ${error instanceof Error ? error.message : String(error)}`,
|
|
@@ -9447,6 +9466,32 @@ var IMAGE_MODEL_CATALOGUE = {
|
|
|
9447
9466
|
max_images: 4,
|
|
9448
9467
|
aspect_ratios: ["1:1", "3:4", "4:3", "9:16", "16:9"],
|
|
9449
9468
|
supports_seed: true
|
|
9469
|
+
},
|
|
9470
|
+
/**
|
|
9471
|
+
* Stufe 6.9.2, Nachtrag — real gegen Flow geprüft (2026-08-17): Der
|
|
9472
|
+
* Modellwähler im Flow-„Generieren"-Tab zeigt aktuell nur "Nano Banana Pro"
|
|
9473
|
+
* und "Nano Banana 2" als wählbar an, "Imagen 4" erscheint dort ausgegraut.
|
|
9474
|
+
* `provider: 'flow'` statt `'google'` ist bewusst: Diese Modelle sind nur
|
|
9475
|
+
* über `Flow.generate.image` erreichbar, nicht über die direkte
|
|
9476
|
+
* Google-Imagen-REST-Route, die der React-Host benutzt (`reactImageProvider.ts`)
|
|
9477
|
+
* — React meldet sie deshalb korrekt als `unsupported`, ohne eine eigene
|
|
9478
|
+
* Host-Verzweigung zu brauchen (D-115/R-1: `hasAccess` prüft `provider`).
|
|
9479
|
+
*/
|
|
9480
|
+
nano_banana_pro: {
|
|
9481
|
+
callable_model_id: "flow-nano-banana-pro",
|
|
9482
|
+
provider: "flow",
|
|
9483
|
+
max_images: 4,
|
|
9484
|
+
// Flow.generate.image dokumentiert nur '1:1' | '16:9' | '9:16' (howto-flow-sdk.md).
|
|
9485
|
+
aspect_ratios: ["1:1", "16:9", "9:16"],
|
|
9486
|
+
// Weder als Eingabe- noch als Ausgabeparameter dokumentiert — nichts erfunden (D-107).
|
|
9487
|
+
supports_seed: false
|
|
9488
|
+
},
|
|
9489
|
+
nano_banana_2: {
|
|
9490
|
+
callable_model_id: "flow-nano-banana-2",
|
|
9491
|
+
provider: "flow",
|
|
9492
|
+
max_images: 4,
|
|
9493
|
+
aspect_ratios: ["1:1", "16:9", "9:16"],
|
|
9494
|
+
supports_seed: false
|
|
9450
9495
|
}
|
|
9451
9496
|
};
|
|
9452
9497
|
function callableImageModelFor(targetModelKey) {
|
|
@@ -11030,7 +11075,9 @@ function createClientRunPort(options) {
|
|
|
11030
11075
|
|
|
11031
11076
|
// src/lib/szenen/flowImageProvider.ts
|
|
11032
11077
|
var FLOW_MODEL_DISPLAY_NAMES = {
|
|
11033
|
-
"imagen-4.0-generate-001": "Imagen 4"
|
|
11078
|
+
"imagen-4.0-generate-001": "Imagen 4",
|
|
11079
|
+
"flow-nano-banana-pro": "\u{1F34C} Nano Banana Pro",
|
|
11080
|
+
"flow-nano-banana-2": "\u{1F34C} Nano Banana 2"
|
|
11034
11081
|
};
|
|
11035
11082
|
function flowImageProviderHasAccess(model) {
|
|
11036
11083
|
return model.callable_model_id in FLOW_MODEL_DISPLAY_NAMES;
|
package/dist/szenen.mjs
CHANGED
|
@@ -130,7 +130,7 @@ import {
|
|
|
130
130
|
validateElementVersion,
|
|
131
131
|
validatePayload,
|
|
132
132
|
withReference
|
|
133
|
-
} from "./chunk-
|
|
133
|
+
} from "./chunk-MILMVOK7.mjs";
|
|
134
134
|
import {
|
|
135
135
|
ContractViolation,
|
|
136
136
|
STYLE_PAYLOAD,
|
|
@@ -144,7 +144,7 @@ import {
|
|
|
144
144
|
preferredVersionId,
|
|
145
145
|
resolvePreferredHead
|
|
146
146
|
} from "./chunk-FUY2OCVC.mjs";
|
|
147
|
-
import "./chunk-
|
|
147
|
+
import "./chunk-LFPOXNOZ.mjs";
|
|
148
148
|
|
|
149
149
|
// src/lib/szenen/providerCheckStore.ts
|
|
150
150
|
function collectProviderChecks(events) {
|