pixelkiln 0.65.0 → 0.66.0
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/cli.js +209 -17
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +209 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +252 -86
- package/dist/index.d.ts +252 -86
- package/dist/index.js +209 -17
- package/dist/index.js.map +1 -1
- package/docs/CHARACTERS.md +10 -0
- package/docs/GENERATORS.md +44 -0
- package/docs/MANIFEST.md +3 -2
- package/docs/REVISIONS.md +13 -0
- package/package.json +1 -1
- package/schema/manifest.schema.json +10 -2
- package/schema/recipe.schema.json +2 -1
- package/skills/pixelkiln/references/pixellab-roadmap.md +9 -6
- package/skills/pixelkiln/references/pixellab.md +10 -0
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/types.ts
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
var MediaTypeSchema = z.enum(["image/png", "image/gif"]);
|
|
4
|
-
var GeneratorSchema = z.enum(["1dir", "map", "pixflux", "tiles", "animation", "frames", "character", "terrain", "imagePro", "isometricTile", "objectPro", "uiAsset", "uiElement"]);
|
|
4
|
+
var GeneratorSchema = z.enum(["1dir", "map", "pixflux", "tiles", "animation", "frames", "character", "terrain", "imagePro", "isometricTile", "objectPro", "uiAsset", "uiElement", "imageProFlash"]);
|
|
5
5
|
var GridConfidenceSchema = z.enum(["low", "medium", "high"]);
|
|
6
6
|
var RevisionModeSchema = z.enum([
|
|
7
7
|
"image-to-image",
|
|
@@ -328,8 +328,22 @@ var RevisionSchema = z.object({
|
|
|
328
328
|
/** `animate-pixminimax` only: facing direction, used only alongside `enhancePrompt` to hold the sprite's facing. */
|
|
329
329
|
direction: CharacterDirectionSchema.optional(),
|
|
330
330
|
/** `animate`/`animate-pixminimax` only: let PixelLab expand the action into a fuller motion description first. */
|
|
331
|
-
enhancePrompt: z.boolean().optional()
|
|
331
|
+
enhancePrompt: z.boolean().optional(),
|
|
332
|
+
/**
|
|
333
|
+
* `image-to-image`/`inpaint` only: which provider engine draws the
|
|
334
|
+
* edit. `pro-flash` selects PixelLab's Pro Flash edit and inpaint tier
|
|
335
|
+
* (`/edit-image-pro-flash`, `/inpaint-image-pro-flash`) instead of the
|
|
336
|
+
* default Pro endpoints; omit it for the default.
|
|
337
|
+
*/
|
|
338
|
+
engine: z.enum(["pro-flash"]).optional()
|
|
332
339
|
}).strict().superRefine((revision, context) => {
|
|
340
|
+
if (revision.engine !== void 0 && revision.mode !== "image-to-image" && revision.mode !== "inpaint") {
|
|
341
|
+
context.addIssue({
|
|
342
|
+
code: z.ZodIssueCode.custom,
|
|
343
|
+
message: "engine applies to image-to-image and inpaint revisions only",
|
|
344
|
+
path: ["engine"]
|
|
345
|
+
});
|
|
346
|
+
}
|
|
333
347
|
if (revision.mode === "inpaint" && !revision.mask) {
|
|
334
348
|
context.addIssue({
|
|
335
349
|
code: z.ZodIssueCode.custom,
|
|
@@ -618,8 +632,8 @@ var StyleObjectSchema = z.object({
|
|
|
618
632
|
/** `character` only. Body template: `mannequin` (default), a quadruped (`bear`, `cat`, `dog`, `horse`, `lion`), or `custom` for `pro-flash`. */
|
|
619
633
|
template: z.string().min(1).optional(),
|
|
620
634
|
/**
|
|
621
|
-
* `character`
|
|
622
|
-
* the style image lends. Each defaults to true.
|
|
635
|
+
* `character` `pro-flash` bases and `imageProFlash` styles, with a
|
|
636
|
+
* style image: which traits the style image lends. Each defaults to true.
|
|
623
637
|
*/
|
|
624
638
|
styleTraits: z.object({
|
|
625
639
|
palette: z.boolean().optional(),
|
|
@@ -1052,7 +1066,8 @@ var LockEntrySchema = z.object({
|
|
|
1052
1066
|
fps: z.number().int().min(1).max(60).optional(),
|
|
1053
1067
|
lastFrameSha256: z.string().regex(/^[0-9a-f]{64}$/).optional(),
|
|
1054
1068
|
direction: CharacterDirectionSchema.optional(),
|
|
1055
|
-
enhancePrompt: z.boolean().optional()
|
|
1069
|
+
enhancePrompt: z.boolean().optional(),
|
|
1070
|
+
engine: z.enum(["pro-flash"]).optional()
|
|
1056
1071
|
}).strict().nullable().default(null),
|
|
1057
1072
|
/** For a mirror: the asset it flips and a hash over that asset's output hashes when this was made. */
|
|
1058
1073
|
mirror: z.object({
|
|
@@ -1429,6 +1444,14 @@ var CorrectPixelartResponseSchema = z2.object({
|
|
|
1429
1444
|
images: z2.array(z2.object({ base64: z2.string().min(1) }).passthrough()).min(1),
|
|
1430
1445
|
usage: z2.unknown().optional()
|
|
1431
1446
|
}).passthrough();
|
|
1447
|
+
var ProFlashImageSubmitSchema = z2.object({
|
|
1448
|
+
background_job_id: z2.string().min(1),
|
|
1449
|
+
image_id: z2.string().min(1),
|
|
1450
|
+
source_image_id: z2.string().min(1),
|
|
1451
|
+
status: z2.string().default("processing"),
|
|
1452
|
+
estimated_generations: z2.number().nullable().optional(),
|
|
1453
|
+
usage: z2.unknown().optional()
|
|
1454
|
+
}).passthrough();
|
|
1432
1455
|
var UnzoomResponseSchema = z2.object({
|
|
1433
1456
|
image: z2.object({ base64: z2.string().min(1) }).passthrough(),
|
|
1434
1457
|
original_size: z2.object({ width: z2.number().int(), height: z2.number().int() }).passthrough(),
|
|
@@ -1869,7 +1892,7 @@ var PixelLabClient = class {
|
|
|
1869
1892
|
const body = {
|
|
1870
1893
|
description: args.description,
|
|
1871
1894
|
n_directions: args.directions,
|
|
1872
|
-
...args.reference ? { first_frame: encode(args.reference) } : { image_size: { width: args.size, height: args.size } },
|
|
1895
|
+
...args.sourceImageId ? { source_image_id: args.sourceImageId } : args.reference ? { first_frame: encode(args.reference) } : { image_size: { width: args.size, height: args.size } },
|
|
1873
1896
|
...args.view ? { view: args.view } : {},
|
|
1874
1897
|
...args.seed != null ? { seed: args.seed } : {},
|
|
1875
1898
|
...args.styleReference && args.styleReferenceSize ? {
|
|
@@ -2016,8 +2039,9 @@ var PixelLabClient = class {
|
|
|
2016
2039
|
description: args.description,
|
|
2017
2040
|
template_id: args.template,
|
|
2018
2041
|
n_directions: 8,
|
|
2019
|
-
// The author's sprite sets the canvas; a size only applies to text
|
|
2020
|
-
|
|
2042
|
+
// The author's sprite sets the canvas; a size only applies to text
|
|
2043
|
+
// creation. An owned copy of the same sprite is referenced by id.
|
|
2044
|
+
...args.sourceImageId ? { source_image_id: args.sourceImageId } : south ? { first_frame: encode(south) } : { image_size: imageSize },
|
|
2021
2045
|
...args.view ? { view: args.view } : {},
|
|
2022
2046
|
...args.seed != null ? { seed: args.seed } : {},
|
|
2023
2047
|
...args.styleReference && args.styleReferenceSize ? {
|
|
@@ -2289,6 +2313,66 @@ var PixelLabClient = class {
|
|
|
2289
2313
|
"generate-image-v2"
|
|
2290
2314
|
);
|
|
2291
2315
|
}
|
|
2316
|
+
/**
|
|
2317
|
+
* `/create-image-pro-flash`: one native pixel-art image from a
|
|
2318
|
+
* description, optionally styled after a style image with per-trait
|
|
2319
|
+
* toggles, on the same Pro Flash model `character`/`objectPro` use for
|
|
2320
|
+
* their `pro-flash` engine. Sizes run 16 to 256 per side in multiples of 4.
|
|
2321
|
+
* A plain background job; `pollRevision`'s generic reader takes the
|
|
2322
|
+
* finished image. The response's `source_image_id` is what a Pro Flash
|
|
2323
|
+
* character or object can reuse instead of an upload.
|
|
2324
|
+
*/
|
|
2325
|
+
async createImageProFlash(args) {
|
|
2326
|
+
const body = {
|
|
2327
|
+
description: args.description,
|
|
2328
|
+
image_size: { width: args.width, height: args.height }
|
|
2329
|
+
};
|
|
2330
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
2331
|
+
if (args.seed != null) body.seed = args.seed;
|
|
2332
|
+
if (args.styleImage) {
|
|
2333
|
+
body.style_image = { image: args.styleImage.image, size: { width: args.styleImage.width, height: args.styleImage.height } };
|
|
2334
|
+
const traits = args.styleTraits;
|
|
2335
|
+
if (traits) {
|
|
2336
|
+
body.style_options = {
|
|
2337
|
+
...traits.palette !== void 0 ? { color_palette: traits.palette } : {},
|
|
2338
|
+
...traits.outline !== void 0 ? { outline: traits.outline } : {},
|
|
2339
|
+
...traits.detail !== void 0 ? { detail: traits.detail } : {},
|
|
2340
|
+
...traits.shading !== void 0 ? { shading: traits.shading } : {}
|
|
2341
|
+
};
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
return validateResponse(
|
|
2345
|
+
ProFlashImageSubmitSchema,
|
|
2346
|
+
await this.request("/create-image-pro-flash", { method: "POST", body: JSON.stringify(body) }),
|
|
2347
|
+
"create-image-pro-flash"
|
|
2348
|
+
);
|
|
2349
|
+
}
|
|
2350
|
+
/** `/edit-image-pro-flash`, text method: edit one image at its own size. The canvas never grows or resizes. */
|
|
2351
|
+
async editImageProFlash(args) {
|
|
2352
|
+
const body = { image: args.image, method: "text", description: args.description };
|
|
2353
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
2354
|
+
if (args.seed != null) body.seed = args.seed;
|
|
2355
|
+
return validateResponse(
|
|
2356
|
+
ProFlashImageSubmitSchema,
|
|
2357
|
+
await this.request("/edit-image-pro-flash", { method: "POST", body: JSON.stringify(body) }),
|
|
2358
|
+
"edit-image-pro-flash"
|
|
2359
|
+
);
|
|
2360
|
+
}
|
|
2361
|
+
/**
|
|
2362
|
+
* `/inpaint-image-pro-flash`: replace only the white pixels of a same-size
|
|
2363
|
+
* black/white mask, keeping everything else exactly. `Modify current
|
|
2364
|
+
* layer` (the endpoint's default) returns the full composite.
|
|
2365
|
+
*/
|
|
2366
|
+
async inpaintImageProFlash(args) {
|
|
2367
|
+
const body = { image: args.image, mask_image: args.maskImage, description: args.description };
|
|
2368
|
+
if (args.noBackground != null) body.no_background = args.noBackground;
|
|
2369
|
+
if (args.seed != null) body.seed = args.seed;
|
|
2370
|
+
return validateResponse(
|
|
2371
|
+
ProFlashImageSubmitSchema,
|
|
2372
|
+
await this.request("/inpaint-image-pro-flash", { method: "POST", body: JSON.stringify(body) }),
|
|
2373
|
+
"inpaint-image-pro-flash"
|
|
2374
|
+
);
|
|
2375
|
+
}
|
|
2292
2376
|
/**
|
|
2293
2377
|
* `/generate-ui-v2` ("Generate UI (Pro)"): one UI element (a button, a
|
|
2294
2378
|
* health bar, an inventory slot, a dialogue box) from a description,
|
|
@@ -3169,6 +3253,7 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
|
|
|
3169
3253
|
uiPieces: spec.uiPieces,
|
|
3170
3254
|
uiElements: spec.uiElements,
|
|
3171
3255
|
uiColorPalette: spec.uiColorPalette,
|
|
3256
|
+
styleTraits: spec.styleTraits,
|
|
3172
3257
|
styleImages: styleImageHashes,
|
|
3173
3258
|
// A character family: the engine and rotations of a base, the parent's
|
|
3174
3259
|
// generated bytes for a state or animation (so a regenerated parent
|
|
@@ -3245,7 +3330,8 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
|
|
|
3245
3330
|
fps: spec.revision.fps,
|
|
3246
3331
|
lastFrameSha256: spec.revision.lastFrameSha256,
|
|
3247
3332
|
direction: spec.revision.direction,
|
|
3248
|
-
enhancePrompt: spec.revision.enhancePrompt
|
|
3333
|
+
enhancePrompt: spec.revision.enhancePrompt,
|
|
3334
|
+
engine: spec.revision.engine
|
|
3249
3335
|
} : void 0
|
|
3250
3336
|
})
|
|
3251
3337
|
);
|
|
@@ -3301,8 +3387,11 @@ function proFlashCharacterCost(width, height, fromReference) {
|
|
|
3301
3387
|
const side = Math.max(32, Math.ceil(Math.max(width, height) / 4) * 4);
|
|
3302
3388
|
const rotations = Math.max(1, Math.ceil(side * side * 8 / 65536));
|
|
3303
3389
|
if (fromReference) return rotations;
|
|
3304
|
-
|
|
3305
|
-
|
|
3390
|
+
return proFlashImageCost(side, side) + rotations;
|
|
3391
|
+
}
|
|
3392
|
+
function proFlashImageCost(width, height) {
|
|
3393
|
+
const side = Math.max(width, height);
|
|
3394
|
+
return side <= 96 ? 5 : side <= 208 ? 6 : 9;
|
|
3306
3395
|
}
|
|
3307
3396
|
function characterAnimationName(spec) {
|
|
3308
3397
|
return `pixelkiln:${spec.styleId}/${spec.assetId}`;
|
|
@@ -3378,7 +3467,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3378
3467
|
return new _PixelLabProvider(new PixelLabClient("download-only"));
|
|
3379
3468
|
}
|
|
3380
3469
|
supports(generator) {
|
|
3381
|
-
return generator === "1dir" || generator === "map" || generator === "pixflux" || generator === "tiles" || generator === "terrain" || generator === "imagePro" || generator === "character" || generator === "isometricTile" || generator === "objectPro" || generator === "uiAsset" || generator === "uiElement";
|
|
3470
|
+
return generator === "1dir" || generator === "map" || generator === "pixflux" || generator === "tiles" || generator === "terrain" || generator === "imagePro" || generator === "character" || generator === "isometricTile" || generator === "objectPro" || generator === "uiAsset" || generator === "uiElement" || generator === "imageProFlash";
|
|
3382
3471
|
}
|
|
3383
3472
|
/**
|
|
3384
3473
|
* `inpaint` (`/inpaint-v3`, a mask) and `image-to-image` (`/edit-images-v2`,
|
|
@@ -3440,6 +3529,13 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3440
3529
|
const base = Math.max(1, Math.ceil(width * height * frames / 65536));
|
|
3441
3530
|
return { unit: "generations", amount: spec.revision.enhancePrompt ? base + 0.05 : base, candidates: 1 };
|
|
3442
3531
|
}
|
|
3532
|
+
if (spec.revision?.engine === "pro-flash") {
|
|
3533
|
+
return {
|
|
3534
|
+
unit: "generations",
|
|
3535
|
+
amount: proFlashImageCost(spec.revision.sourceWidth ?? spec.width, spec.revision.sourceHeight ?? spec.height),
|
|
3536
|
+
candidates: 1
|
|
3537
|
+
};
|
|
3538
|
+
}
|
|
3443
3539
|
if (spec.revision) {
|
|
3444
3540
|
const width = spec.revision.sourceWidth ?? spec.width;
|
|
3445
3541
|
const height = spec.revision.sourceHeight ?? spec.height;
|
|
@@ -3454,6 +3550,9 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3454
3550
|
if (spec.generator === "objectPro") {
|
|
3455
3551
|
return { unit: "generations", amount: objectProCost(spec), candidates: 1 };
|
|
3456
3552
|
}
|
|
3553
|
+
if (spec.generator === "imageProFlash") {
|
|
3554
|
+
return { unit: "generations", amount: proFlashImageCost(spec.width, spec.height), candidates: 1 };
|
|
3555
|
+
}
|
|
3457
3556
|
return {
|
|
3458
3557
|
unit: "generations",
|
|
3459
3558
|
amount: generationCost(spec.width, spec.height, spec.generator),
|
|
@@ -3467,7 +3566,17 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3467
3566
|
`PixelLab ${spec.revision.mode} reads one source image; ${spec.revision.sourceAssetId} is a ${members.length}-member set (${members[0].role}, ...). Revise one member through a declared source, or use reduce-colors, correct-pixelart, or edit-animation, which take the whole set`
|
|
3468
3567
|
);
|
|
3469
3568
|
}
|
|
3470
|
-
if (spec.revision?.
|
|
3569
|
+
if (spec.revision?.engine === "pro-flash") {
|
|
3570
|
+
const { sourceWidth: width, sourceHeight: height, mode: mode2 } = spec.revision;
|
|
3571
|
+
if (width != null && height != null && (width < 32 || height < 32 || width > 256 || height > 256 || width % 4 || height % 4)) {
|
|
3572
|
+
throw new Error(
|
|
3573
|
+
`PixelLab pro-flash ${mode2} source is ${width}x${height}; the API takes 32 to 256 pixels per side, in multiples of 4`
|
|
3574
|
+
);
|
|
3575
|
+
}
|
|
3576
|
+
if (spec.revision.strength != null) {
|
|
3577
|
+
throw new Error(`PixelLab pro-flash ${mode2} takes no strength; the edit applies in full`);
|
|
3578
|
+
}
|
|
3579
|
+
} else if (spec.revision?.mode === "inpaint") {
|
|
3471
3580
|
const { sourceWidth: width, sourceHeight: height } = spec.revision;
|
|
3472
3581
|
if (width != null && height != null && (width < 32 || height < 32 || width > 512 || height > 512)) {
|
|
3473
3582
|
throw new Error(`PixelLab inpaint source is ${width}x${height}; the API takes 32 to 512 pixels per side`);
|
|
@@ -3548,6 +3657,19 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3548
3657
|
`PixelLab uiAsset is ${spec.width}x${spec.height}; the API takes 192 to 688 pixels per side (the exact ceiling also depends on aspect ratio \u2014 square tops out at 512, 16:9 at 688x384, 9:16 at 384x688, 4:3 at 600x448, 3:4 at 448x600)`
|
|
3549
3658
|
);
|
|
3550
3659
|
}
|
|
3660
|
+
if (spec.generator === "imageProFlash") {
|
|
3661
|
+
if (spec.width < 16 || spec.height < 16 || spec.width > 256 || spec.height > 256 || spec.width % 4 || spec.height % 4) {
|
|
3662
|
+
throw new Error(
|
|
3663
|
+
`PixelLab imageProFlash is ${spec.width}x${spec.height}; the API takes 16 to 256 pixels per side, in multiples of 4`
|
|
3664
|
+
);
|
|
3665
|
+
}
|
|
3666
|
+
if (styleImages.length > 1) {
|
|
3667
|
+
throw new Error("PixelLab imageProFlash takes one style image; list at most one styleImages entry");
|
|
3668
|
+
}
|
|
3669
|
+
if (spec.styleTraits && !styleImages.length) {
|
|
3670
|
+
throw new Error("PixelLab imageProFlash: styleTraits choose what a style image lends; add a styleImages entry or drop them");
|
|
3671
|
+
}
|
|
3672
|
+
}
|
|
3551
3673
|
if (spec.generator === "uiElement" && (spec.width < 16 || spec.height < 16 || spec.width > 792 || spec.height > 688)) {
|
|
3552
3674
|
throw new Error(
|
|
3553
3675
|
`PixelLab uiElement is ${spec.width}x${spec.height}; the API takes 16 to 792 wide and 16 to 688 tall (the exact ceiling depends on aspect ratio \u2014 square tops out at 512, 16:9 at 688x384)`
|
|
@@ -3901,7 +4023,8 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
3901
4023
|
concept: character.concept ? readPose(spec, "concept image", character.concept) : void 0,
|
|
3902
4024
|
styleCharacterId: character.styleAnchor ? requireStyleObjectId(spec, context) : void 0,
|
|
3903
4025
|
styleReferenceSize: styleImage ? { width: styleImage.width, height: styleImage.height } : void 0,
|
|
3904
|
-
styleTraits: character.styleTraits
|
|
4026
|
+
styleTraits: character.styleTraits,
|
|
4027
|
+
sourceImageId: character.mode === "pro-flash" ? context?.referenceSourceImageId : void 0
|
|
3905
4028
|
});
|
|
3906
4029
|
return { jobId: res2.character_id, metadata: { character: { kind: "base", characterId: res2.character_id, mode: character.mode, directions: character.directions, backgroundJobId: res2.background_job_id } } };
|
|
3907
4030
|
}
|
|
@@ -4036,7 +4159,8 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4036
4159
|
reference: object.reference ? readPose(spec, "reference sprite", object.reference) : void 0,
|
|
4037
4160
|
styleReference: styleImage ? { base64: styleImage.base64, format: styleImage.format } : void 0,
|
|
4038
4161
|
styleReferenceSize: styleImage ? { width: styleImage.width, height: styleImage.height } : void 0,
|
|
4039
|
-
styleTraits: object.styleTraits
|
|
4162
|
+
styleTraits: object.styleTraits,
|
|
4163
|
+
sourceImageId: context?.referenceSourceImageId
|
|
4040
4164
|
});
|
|
4041
4165
|
return { jobId: res2.object_id, metadata: { objectPro: { kind: "base", objectId: res2.object_id, directions: object.directions, backgroundJobId: res2.background_job_id } } };
|
|
4042
4166
|
}
|
|
@@ -4335,6 +4459,19 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4335
4459
|
});
|
|
4336
4460
|
return { jobId: res2.ui_asset_id, metadata: { backgroundJobId: res2.background_job_id } };
|
|
4337
4461
|
}
|
|
4462
|
+
if (spec.generator === "imageProFlash") {
|
|
4463
|
+
const style = styleImages[0];
|
|
4464
|
+
const res2 = await this.client.createImageProFlash({
|
|
4465
|
+
description: spec.prompt,
|
|
4466
|
+
width: spec.width,
|
|
4467
|
+
height: spec.height,
|
|
4468
|
+
noBackground: spec.noBackground,
|
|
4469
|
+
seed: spec.seed,
|
|
4470
|
+
styleImage: style ? { image: { base64: style.base64, format: style.format }, width: style.width, height: style.height } : void 0,
|
|
4471
|
+
styleTraits: spec.styleTraits
|
|
4472
|
+
});
|
|
4473
|
+
return { jobId: res2.background_job_id, metadata: { imageProFlash: proFlashRecord(res2) } };
|
|
4474
|
+
}
|
|
4338
4475
|
if (spec.generator === "uiElement") {
|
|
4339
4476
|
const concept = styleImages[0];
|
|
4340
4477
|
const res2 = await this.client.generateUiV2({
|
|
@@ -4488,6 +4625,32 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4488
4625
|
const width = revision.sourceWidth;
|
|
4489
4626
|
const height = revision.sourceHeight;
|
|
4490
4627
|
const roles = revision.sourceMembers?.map((member) => member.role);
|
|
4628
|
+
if (revision.engine === "pro-flash") {
|
|
4629
|
+
if (revision.mode === "inpaint") {
|
|
4630
|
+
if (!revision.maskFile || !revision.maskSha256 || !revision.maskFormat) {
|
|
4631
|
+
throw new Error(`${spec.styleId}/${spec.assetId}: revision mask is not ready`);
|
|
4632
|
+
}
|
|
4633
|
+
const maskBytes = readFileSync(revision.maskFile);
|
|
4634
|
+
if (sha256(maskBytes) !== revision.maskSha256) {
|
|
4635
|
+
throw new Error(`${spec.styleId}/${spec.assetId}: revision mask changed after the manifest was resolved`);
|
|
4636
|
+
}
|
|
4637
|
+
const res3 = await this.client.inpaintImageProFlash({
|
|
4638
|
+
image,
|
|
4639
|
+
maskImage: { base64: maskBytes.toString("base64"), format: revision.maskFormat },
|
|
4640
|
+
description: spec.prompt,
|
|
4641
|
+
noBackground: spec.noBackground,
|
|
4642
|
+
seed: spec.seed
|
|
4643
|
+
});
|
|
4644
|
+
return { jobId: res3.background_job_id, metadata: { imageProFlash: proFlashRecord(res3) } };
|
|
4645
|
+
}
|
|
4646
|
+
const res2 = await this.client.editImageProFlash({
|
|
4647
|
+
image,
|
|
4648
|
+
description: spec.prompt,
|
|
4649
|
+
noBackground: spec.noBackground,
|
|
4650
|
+
seed: spec.seed
|
|
4651
|
+
});
|
|
4652
|
+
return { jobId: res2.background_job_id, metadata: { imageProFlash: proFlashRecord(res2) } };
|
|
4653
|
+
}
|
|
4491
4654
|
if (revision.mode === "inpaint") {
|
|
4492
4655
|
if (!revision.maskFile || !revision.maskSha256 || !revision.maskFormat) {
|
|
4493
4656
|
throw new Error(`${spec.styleId}/${spec.assetId}: revision mask is not ready`);
|
|
@@ -4652,6 +4815,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4652
4815
|
return this.pollAnimateRevision(jobId, context);
|
|
4653
4816
|
}
|
|
4654
4817
|
if (context?.spec?.revision) return this.pollRevision(jobId);
|
|
4818
|
+
if (generator === "imageProFlash") return this.pollRevision(jobId);
|
|
4655
4819
|
if (generator === "pixflux") {
|
|
4656
4820
|
const file = path.join(_PixelLabProvider.cacheDir(), `${jobId}.png`);
|
|
4657
4821
|
if (existsSync(file)) {
|
|
@@ -5232,6 +5396,13 @@ function readPose(spec, what, image) {
|
|
|
5232
5396
|
}
|
|
5233
5397
|
return { base64: bytes.toString("base64"), format: image.format };
|
|
5234
5398
|
}
|
|
5399
|
+
function proFlashRecord(res) {
|
|
5400
|
+
return {
|
|
5401
|
+
imageId: res.image_id,
|
|
5402
|
+
sourceImageId: res.source_image_id,
|
|
5403
|
+
...res.estimated_generations != null ? { estimatedGenerations: res.estimated_generations } : {}
|
|
5404
|
+
};
|
|
5405
|
+
}
|
|
5235
5406
|
function editAnimationFrameCeiling(width, height) {
|
|
5236
5407
|
const side = Math.max(width, height);
|
|
5237
5408
|
if (side <= 64) return 16;
|
|
@@ -6435,6 +6606,11 @@ var ComfyUIProvider = class _ComfyUIProvider {
|
|
|
6435
6606
|
throw new Error("ComfyUI providerOptions.frames requires generator: frames");
|
|
6436
6607
|
}
|
|
6437
6608
|
if (spec.revision) {
|
|
6609
|
+
if (spec.revision.engine) {
|
|
6610
|
+
throw new Error(
|
|
6611
|
+
`ComfyUI has no "${spec.revision.engine}" revision engine; that selects PixelLab's Pro Flash edit/inpaint endpoints. Drop engine to run the revision through this style's own workflow.`
|
|
6612
|
+
);
|
|
6613
|
+
}
|
|
6438
6614
|
if (spec.revision.sourceMembers) {
|
|
6439
6615
|
throw new Error(
|
|
6440
6616
|
`ComfyUI revisions read one source image; ${spec.revision.sourceAssetId} is a ${spec.revision.sourceMembers.length}-member set (directions or frames)`
|
|
@@ -8032,6 +8208,7 @@ async function resolveSpecs(loaded, filter) {
|
|
|
8032
8208
|
uiPieces: generator === "uiAsset" ? asset.pieces : void 0,
|
|
8033
8209
|
uiElements: generator === "uiAsset" ? asset.elements : void 0,
|
|
8034
8210
|
uiColorPalette: generator === "uiAsset" || generator === "uiElement" ? style.uiColorPalette : void 0,
|
|
8211
|
+
...generator === "imageProFlash" && style.styleTraits ? { styleTraits: style.styleTraits } : {},
|
|
8035
8212
|
palette: style.palette,
|
|
8036
8213
|
enforcePalette: style.enforcePalette,
|
|
8037
8214
|
noBackground: style.noBackground,
|
|
@@ -8315,7 +8492,8 @@ async function resolveSpecs(loaded, filter) {
|
|
|
8315
8492
|
lastFrameFormat: lastFrame?.format ?? null
|
|
8316
8493
|
} : {},
|
|
8317
8494
|
...asset.revision.direction ? { direction: asset.revision.direction } : {},
|
|
8318
|
-
...asset.revision.enhancePrompt == null ? {} : { enhancePrompt: asset.revision.enhancePrompt }
|
|
8495
|
+
...asset.revision.enhancePrompt == null ? {} : { enhancePrompt: asset.revision.enhancePrompt },
|
|
8496
|
+
...asset.revision.engine ? { engine: asset.revision.engine } : {}
|
|
8319
8497
|
};
|
|
8320
8498
|
}
|
|
8321
8499
|
if (asset.batch) {
|
|
@@ -13087,7 +13265,8 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
|
|
|
13087
13265
|
...spec.revision.fps == null ? {} : { fps: spec.revision.fps },
|
|
13088
13266
|
...spec.revision.lastFrameSha256 ? { lastFrameSha256: spec.revision.lastFrameSha256 } : {},
|
|
13089
13267
|
...spec.revision.direction ? { direction: spec.revision.direction } : {},
|
|
13090
|
-
...spec.revision.enhancePrompt == null ? {} : { enhancePrompt: spec.revision.enhancePrompt }
|
|
13268
|
+
...spec.revision.enhancePrompt == null ? {} : { enhancePrompt: spec.revision.enhancePrompt },
|
|
13269
|
+
...spec.revision.engine ? { engine: spec.revision.engine } : {}
|
|
13091
13270
|
} : null,
|
|
13092
13271
|
outfit: spec.character?.kind === "outfit" && outfitParentEntry ? {
|
|
13093
13272
|
sourceAssetId: spec.character.parentAssetId,
|
|
@@ -13131,8 +13310,10 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
|
|
|
13131
13310
|
path: currentEntryOutputPath(parentEntry, spec.character.parentSpec, index),
|
|
13132
13311
|
role: output.role
|
|
13133
13312
|
})) : void 0;
|
|
13313
|
+
const referenceSourceImageId = ownedReferenceImageId(spec, lock, provider.id);
|
|
13134
13314
|
const { jobId, metadata } = await provider.submit(spec, refs, {
|
|
13135
13315
|
...previousJobId ? { previousJobId } : {},
|
|
13316
|
+
...referenceSourceImageId ? { referenceSourceImageId } : {},
|
|
13136
13317
|
...parentEntry?.objectId ? { parentObjectId: parentEntry.objectId } : {},
|
|
13137
13318
|
...anchorEntry?.objectId ? { styleObjectId: anchorEntry.objectId } : {},
|
|
13138
13319
|
...parentOutputs ? { parentOutputs } : {},
|
|
@@ -13199,6 +13380,17 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
|
|
|
13199
13380
|
}
|
|
13200
13381
|
return { submitted, failed, spent, unit };
|
|
13201
13382
|
}
|
|
13383
|
+
function ownedReferenceImageId(spec, lock, providerId) {
|
|
13384
|
+
const sha2562 = spec.character?.kind === "base" && spec.character.mode === "pro-flash" ? spec.character.reference?.south?.sha256 : spec.objectPro?.kind === "base" ? spec.objectPro.reference?.sha256 : void 0;
|
|
13385
|
+
if (!sha2562) return void 0;
|
|
13386
|
+
for (const entry of Object.values(lock.entries)) {
|
|
13387
|
+
if (entry.provider !== providerId || entry.generator !== "imageProFlash" || entry.status !== "downloaded") continue;
|
|
13388
|
+
if (entry.outputs.length !== 1 || entry.outputs[0].sha256 !== sha2562) continue;
|
|
13389
|
+
const recorded = entry.providerMetadata?.[providerId]?.imageProFlash;
|
|
13390
|
+
if (typeof recorded?.sourceImageId === "string" && recorded.sourceImageId) return recorded.sourceImageId;
|
|
13391
|
+
}
|
|
13392
|
+
return void 0;
|
|
13393
|
+
}
|
|
13202
13394
|
|
|
13203
13395
|
// src/pipeline/poll.ts
|
|
13204
13396
|
var sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
|