pixelkiln 0.45.0 → 0.46.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 +82 -17
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +82 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +522 -72
- package/dist/index.d.ts +522 -72
- package/dist/index.js +82 -17
- package/dist/index.js.map +1 -1
- package/docs/GENERATORS.md +1 -0
- package/docs/MANIFEST.md +21 -12
- package/package.json +1 -1
- package/schema/manifest.schema.json +40 -2
- package/schema/recipe.schema.json +20 -1
- package/skills/pixelkiln/references/pixellab.md +1 -1
package/dist/index.cjs
CHANGED
|
@@ -389,7 +389,7 @@ var MIRRORED_DIRECTION = {
|
|
|
389
389
|
west: "east",
|
|
390
390
|
"south-west": "south-east"
|
|
391
391
|
};
|
|
392
|
-
var CharacterModeSchema = import_zod.z.enum(["standard", "v3", "pro"]);
|
|
392
|
+
var CharacterModeSchema = import_zod.z.enum(["standard", "v3", "pro", "pro-flash"]);
|
|
393
393
|
var CHARACTER_PROPORTION_PRESETS = ["default", "chibi", "cartoon", "stylized", "realistic_male", "realistic_female", "heroic"];
|
|
394
394
|
var CharacterProportionsSchema = import_zod.z.union([
|
|
395
395
|
import_zod.z.enum(CHARACTER_PROPORTION_PRESETS),
|
|
@@ -585,14 +585,27 @@ var StyleObjectSchema = import_zod.z.object({
|
|
|
585
585
|
/**
|
|
586
586
|
* `character` only. `standard` draws from a skeleton template for 1
|
|
587
587
|
* generation; `v3` is the highest quality at 2 to 9 by size; `pro` is a
|
|
588
|
-
* reference-based engine at 20 to 40 by size
|
|
589
|
-
*
|
|
588
|
+
* reference-based engine at 20 to 40 by size; `pro-flash` draws a
|
|
589
|
+
* south sprite with PixelLab's newest image model and rotates it with
|
|
590
|
+
* v3, 6 to 17 by size, or the rotations alone (1 at 64px) from a
|
|
591
|
+
* `reference`. States inherit the parent's engine; animations choose
|
|
592
|
+
* their own.
|
|
590
593
|
*/
|
|
591
594
|
mode: CharacterModeSchema.optional(),
|
|
592
|
-
/** `character` only. Rotations per base or state.
|
|
595
|
+
/** `character` only. Rotations per base or state. Every engine but `standard` draws 8. */
|
|
593
596
|
directions: import_zod.z.union([import_zod.z.literal(4), import_zod.z.literal(8)]).optional(),
|
|
594
|
-
/** `character` only. Body template: `mannequin` (default)
|
|
597
|
+
/** `character` only. Body template: `mannequin` (default), a quadruped (`bear`, `cat`, `dog`, `horse`, `lion`), or `custom` for `pro-flash`. */
|
|
595
598
|
template: import_zod.z.string().min(1).optional(),
|
|
599
|
+
/**
|
|
600
|
+
* `character` only, `pro-flash` bases with a style image: which traits
|
|
601
|
+
* the style image lends. Each defaults to true.
|
|
602
|
+
*/
|
|
603
|
+
styleTraits: import_zod.z.object({
|
|
604
|
+
palette: import_zod.z.boolean().optional(),
|
|
605
|
+
outline: import_zod.z.boolean().optional(),
|
|
606
|
+
detail: import_zod.z.boolean().optional(),
|
|
607
|
+
shading: import_zod.z.boolean().optional()
|
|
608
|
+
}).strict().optional(),
|
|
596
609
|
/** `character` only, `standard` humanoid bases. A preset or multipliers; an asset may override it. */
|
|
597
610
|
proportions: CharacterProportionsSchema.optional(),
|
|
598
611
|
/**
|
|
@@ -1561,6 +1574,29 @@ var PixelLabClient = class {
|
|
|
1561
1574
|
...south ? { reference_image: encode(south) } : {},
|
|
1562
1575
|
...args.enhancePrompt ? { enhance_prompt: true } : {}
|
|
1563
1576
|
};
|
|
1577
|
+
} else if (args.mode === "pro-flash") {
|
|
1578
|
+
path33 = "/create-character-pro-flash";
|
|
1579
|
+
const traits = args.styleTraits;
|
|
1580
|
+
body = {
|
|
1581
|
+
description: args.description,
|
|
1582
|
+
template_id: args.template,
|
|
1583
|
+
n_directions: 8,
|
|
1584
|
+
// The author's sprite sets the canvas; a size only applies to text creation.
|
|
1585
|
+
...south ? { first_frame: encode(south) } : { image_size: imageSize },
|
|
1586
|
+
...args.view ? { view: args.view } : {},
|
|
1587
|
+
...args.seed != null ? { seed: args.seed } : {},
|
|
1588
|
+
...args.styleReference && args.styleReferenceSize ? {
|
|
1589
|
+
style_image: { image: encode(args.styleReference), size: args.styleReferenceSize },
|
|
1590
|
+
...traits ? {
|
|
1591
|
+
style_options: {
|
|
1592
|
+
...traits.palette !== void 0 ? { color_palette: traits.palette } : {},
|
|
1593
|
+
...traits.outline !== void 0 ? { outline: traits.outline } : {},
|
|
1594
|
+
...traits.detail !== void 0 ? { detail: traits.detail } : {},
|
|
1595
|
+
...traits.shading !== void 0 ? { shading: traits.shading } : {}
|
|
1596
|
+
}
|
|
1597
|
+
} : {}
|
|
1598
|
+
} : {}
|
|
1599
|
+
};
|
|
1564
1600
|
} else if (args.mode === "pro") {
|
|
1565
1601
|
path33 = "/create-character-pro";
|
|
1566
1602
|
body = {
|
|
@@ -2335,6 +2371,7 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
|
|
|
2335
2371
|
textGuidanceScale: spec.character.textGuidanceScale,
|
|
2336
2372
|
isometric: spec.character.isometric,
|
|
2337
2373
|
enhancePrompt: spec.character.enhancePrompt,
|
|
2374
|
+
styleTraits: spec.character.styleTraits,
|
|
2338
2375
|
reference: spec.character.reference ? Object.fromEntries(Object.entries(spec.character.reference).map(([direction, image]) => [direction, image.sha256])) : void 0,
|
|
2339
2376
|
concept: spec.character.concept?.sha256,
|
|
2340
2377
|
styleAnchor: spec.character.styleAnchor ? { of: spec.character.styleAnchor.assetId, sha256: spec.character.styleAnchor.sha256 } : void 0
|
|
@@ -2378,12 +2415,24 @@ function characterCost(spec) {
|
|
|
2378
2415
|
if (character.kind === "state") return generationCost(spec.width, spec.height, "1dir");
|
|
2379
2416
|
if (character.mode === "standard") return 1;
|
|
2380
2417
|
if (character.mode === "v3") return 1 + Math.max(1, Math.ceil(px * 8 / 65536));
|
|
2418
|
+
if (character.mode === "pro-flash") {
|
|
2419
|
+
const south = character.reference?.south;
|
|
2420
|
+
return south ? proFlashCharacterCost(south.width, south.height, true) : proFlashCharacterCost(spec.width, spec.height, false);
|
|
2421
|
+
}
|
|
2381
2422
|
return generationCost(spec.width, spec.height, "1dir");
|
|
2382
2423
|
}
|
|
2424
|
+
function proFlashCharacterCost(width, height, fromReference) {
|
|
2425
|
+
const side = Math.max(32, Math.ceil(Math.max(width, height) / 4) * 4);
|
|
2426
|
+
const rotations = Math.max(1, Math.ceil(side * side * 8 / 65536));
|
|
2427
|
+
if (fromReference) return rotations;
|
|
2428
|
+
const image = side <= 96 ? 5 : side <= 208 ? 6 : 9;
|
|
2429
|
+
return image + rotations;
|
|
2430
|
+
}
|
|
2383
2431
|
function characterAnimationName(spec) {
|
|
2384
2432
|
return `pixelkiln:${spec.styleId}/${spec.assetId}`;
|
|
2385
2433
|
}
|
|
2386
2434
|
var CHARACTER_TEMPLATES = ["mannequin", "bear", "cat", "dog", "horse", "lion"];
|
|
2435
|
+
var PRO_FLASH_TEMPLATES = [...CHARACTER_TEMPLATES, "custom"];
|
|
2387
2436
|
function encodeAnimationJob(job) {
|
|
2388
2437
|
return `character-animation:${Buffer.from(JSON.stringify(job)).toString("base64url")}`;
|
|
2389
2438
|
}
|
|
@@ -2542,7 +2591,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
2542
2591
|
if (!character.reference.south) throw new Error(`${label}: a reference needs a south-facing sprite`);
|
|
2543
2592
|
if (character.mode !== "standard") {
|
|
2544
2593
|
if (given.length > 1) throw new Error(`${label}: PixelLab ${character.mode} rotates one south-facing reference; drop the other directions`);
|
|
2545
|
-
const limit = character.mode === "
|
|
2594
|
+
const limit = character.mode === "pro" ? 168 : 256;
|
|
2546
2595
|
const south = character.reference.south;
|
|
2547
2596
|
if (south.width > limit || south.height > limit) {
|
|
2548
2597
|
throw new Error(`${label}: reference is ${south.width}x${south.height}; PixelLab ${character.mode} takes up to ${limit}px`);
|
|
@@ -2566,26 +2615,39 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
2566
2615
|
}
|
|
2567
2616
|
}
|
|
2568
2617
|
if (styleImages.length) {
|
|
2569
|
-
if (character.mode !== "pro") {
|
|
2618
|
+
if (character.mode !== "pro" && character.mode !== "pro-flash") {
|
|
2570
2619
|
throw new Error(
|
|
2571
|
-
`PixelLab ${character.mode} characters take no style images; give a base its own sprite with \`reference\`, or use mode pro for a style anchor`
|
|
2620
|
+
`PixelLab ${character.mode} characters take no style images; give a base its own sprite with \`reference\`, or use mode pro or pro-flash for a style anchor`
|
|
2572
2621
|
);
|
|
2573
2622
|
}
|
|
2574
|
-
if (styleImages.length > 1) throw new Error(
|
|
2623
|
+
if (styleImages.length > 1) throw new Error(`PixelLab ${character.mode} characters take one style image`);
|
|
2575
2624
|
if (character.kind === "base" && character.reference) {
|
|
2576
|
-
throw new Error(`${label}: a
|
|
2625
|
+
throw new Error(`${label}: a ${character.mode} base rotating its own reference takes no style image`);
|
|
2577
2626
|
}
|
|
2578
2627
|
const image = styleImages[0];
|
|
2579
|
-
|
|
2580
|
-
|
|
2628
|
+
const limit = character.mode === "pro" ? 168 : 256;
|
|
2629
|
+
if (image.width > limit || image.height > limit) {
|
|
2630
|
+
throw new Error(`PixelLab ${character.mode} character style image is ${image.width}x${image.height}; the limit is ${limit}px`);
|
|
2631
|
+
}
|
|
2632
|
+
if (character.mode === "pro-flash" && (image.width > spec.width || image.height > spec.height)) {
|
|
2633
|
+
throw new Error(
|
|
2634
|
+
`PixelLab pro-flash style image is ${image.width}x${image.height} but the character is ${spec.width}x${spec.height}; crop the image to its subject or raise the style's size`
|
|
2635
|
+
);
|
|
2581
2636
|
}
|
|
2582
2637
|
}
|
|
2583
|
-
|
|
2638
|
+
if (character.styleTraits && character.mode !== "pro-flash") {
|
|
2639
|
+
throw new Error(`${label}: styleTraits choose what a pro-flash style image lends; the ${character.mode} engine does not take them`);
|
|
2640
|
+
}
|
|
2641
|
+
const maxSize = character.mode === "v3" || character.mode === "pro-flash" ? 256 : 128;
|
|
2584
2642
|
if (spec.width < 16 || spec.height < 16 || spec.width > maxSize || spec.height > maxSize) {
|
|
2585
2643
|
throw new Error(`PixelLab ${character.mode} characters must be between 16 and ${maxSize} pixels`);
|
|
2586
2644
|
}
|
|
2587
|
-
if (
|
|
2588
|
-
throw new Error(`PixelLab
|
|
2645
|
+
if (character.mode === "pro-flash" && character.kind === "base" && (spec.width % 4 || spec.height % 4)) {
|
|
2646
|
+
throw new Error(`PixelLab pro-flash characters are sized in multiples of 4 pixels; ${spec.width}x${spec.height} is not`);
|
|
2647
|
+
}
|
|
2648
|
+
const templates = character.mode === "pro-flash" ? PRO_FLASH_TEMPLATES : CHARACTER_TEMPLATES;
|
|
2649
|
+
if (!templates.includes(character.template)) {
|
|
2650
|
+
throw new Error(`PixelLab ${character.mode} character template must be one of: ${templates.join(", ")}`);
|
|
2589
2651
|
}
|
|
2590
2652
|
const views = character.mode === "standard" ? ["low top-down", "high top-down", "side", "perspective", "oblique"] : ["low top-down", "high top-down", "side"];
|
|
2591
2653
|
if (!views.includes(spec.view)) {
|
|
@@ -2640,7 +2702,9 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
2640
2702
|
styleReference: styleImage ? { base64: styleImage.base64, format: styleImage.format } : void 0,
|
|
2641
2703
|
enhancePrompt: character.enhancePrompt,
|
|
2642
2704
|
concept: character.concept ? readPose(spec, "concept image", character.concept) : void 0,
|
|
2643
|
-
styleCharacterId: character.styleAnchor ? requireStyleObjectId(spec, context) : void 0
|
|
2705
|
+
styleCharacterId: character.styleAnchor ? requireStyleObjectId(spec, context) : void 0,
|
|
2706
|
+
styleReferenceSize: styleImage ? { width: styleImage.width, height: styleImage.height } : void 0,
|
|
2707
|
+
styleTraits: character.styleTraits
|
|
2644
2708
|
});
|
|
2645
2709
|
return { jobId: res2.character_id, metadata: { character: { kind: "base", characterId: res2.character_id, mode: character.mode, directions: character.directions, backgroundJobId: res2.background_job_id } } };
|
|
2646
2710
|
}
|
|
@@ -5929,7 +5993,8 @@ async function resolveCharacterShape(asset, style, kind, files) {
|
|
|
5929
5993
|
...proportions !== void 0 ? { proportions } : {},
|
|
5930
5994
|
...style.textGuidanceScale !== void 0 ? { textGuidanceScale: style.textGuidanceScale } : {},
|
|
5931
5995
|
...style.isometric !== void 0 ? { isometric: style.isometric } : {},
|
|
5932
|
-
...style.enhancePrompt !== void 0 ? { enhancePrompt: style.enhancePrompt } : {}
|
|
5996
|
+
...style.enhancePrompt !== void 0 ? { enhancePrompt: style.enhancePrompt } : {},
|
|
5997
|
+
...style.styleTraits ? { styleTraits: style.styleTraits } : {}
|
|
5933
5998
|
};
|
|
5934
5999
|
if (asset.concept) {
|
|
5935
6000
|
const image = await files.load(asset.concept, "Concept image");
|