@pixerate/editor 0.135.0 → 0.137.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/animation-editor/index.cjs +63 -55
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +8 -5
- package/dist/animation-editor/index.d.ts +8 -5
- package/dist/animation-editor/index.js +10 -2
- package/dist/animation-editor/index.js.map +1 -1
- package/dist/{bezier-J8i4uqSH.d.cts → bezier-CZ2AhjID.d.cts} +1 -1
- package/dist/{bezier-lNEOp0Jx.d.ts → bezier-Dywv3Bw8.d.ts} +1 -1
- package/dist/blending-D7jCmjO6.d.cts +1026 -0
- package/dist/blending-NgF3qo3d.d.ts +1026 -0
- package/dist/brushes-CnvZSYYU.d.cts +744 -0
- package/dist/brushes-DJmUbIgz.d.ts +744 -0
- package/dist/{brushstrokeRender-SII6MG4R.js → brushstrokeRender-2FAXA3XC.js} +13 -16
- package/dist/{brushstrokeRender-SII6MG4R.js.map → brushstrokeRender-2FAXA3XC.js.map} +1 -1
- package/dist/{brushstrokeRender-JNHVEUFG.cjs → brushstrokeRender-IMFY3FF6.cjs} +16 -19
- package/dist/brushstrokeRender-IMFY3FF6.cjs.map +1 -0
- package/dist/canvas/index.cjs +10 -10
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +10 -7
- package/dist/canvas/index.d.ts +10 -7
- package/dist/canvas/index.js +4 -4
- package/dist/{chunk-W4LNKTHT.cjs → chunk-2XS6LTUP.cjs} +63 -63
- package/dist/{chunk-W4LNKTHT.cjs.map → chunk-2XS6LTUP.cjs.map} +1 -1
- package/dist/{chunk-HHTCDFZC.js → chunk-3D77LOBM.js} +234 -136
- package/dist/chunk-3D77LOBM.js.map +1 -0
- package/dist/{chunk-BR7EKQUP.js → chunk-3G6J7UFV.js} +322 -2
- package/dist/chunk-3G6J7UFV.js.map +1 -0
- package/dist/{chunk-62XUO5LB.js → chunk-3X6IAJUQ.js} +2 -2
- package/dist/{chunk-EM3FMJWE.js → chunk-5FSRTP6E.js} +320 -3
- package/dist/chunk-5FSRTP6E.js.map +1 -0
- package/dist/{chunk-Z2H7KECK.cjs → chunk-5OOIUXNJ.cjs} +345 -247
- package/dist/chunk-5OOIUXNJ.cjs.map +1 -0
- package/dist/{chunk-7RJ6P7MI.js → chunk-6S6362D2.js} +2 -2
- package/dist/chunk-A3BVTI3G.js +150 -0
- package/dist/chunk-A3BVTI3G.js.map +1 -0
- package/dist/{chunk-24ATT2PE.cjs → chunk-AEAAN4AD.cjs} +120 -120
- package/dist/{chunk-24ATT2PE.cjs.map → chunk-AEAAN4AD.cjs.map} +1 -1
- package/dist/chunk-ECCXGELC.cjs +727 -0
- package/dist/chunk-ECCXGELC.cjs.map +1 -0
- package/dist/{chunk-SVYE5HIM.js → chunk-EQQMGO42.js} +2 -2
- package/dist/{chunk-FHPVDTI2.cjs → chunk-F2Y4E4GU.cjs} +22 -22
- package/dist/{chunk-FHPVDTI2.cjs.map → chunk-F2Y4E4GU.cjs.map} +1 -1
- package/dist/{chunk-OXSV64JX.js → chunk-G6IKY6PL.js} +4 -4
- package/dist/{chunk-UYQUPUR6.js → chunk-HUO3TI4C.js} +3 -3
- package/dist/chunk-I52DRGGJ.js +727 -0
- package/dist/chunk-I52DRGGJ.js.map +1 -0
- package/dist/{chunk-DDSO4HS7.cjs → chunk-KEENUAFN.cjs} +2 -2
- package/dist/{chunk-DDSO4HS7.cjs.map → chunk-KEENUAFN.cjs.map} +1 -1
- package/dist/{chunk-2HC4DRF4.js → chunk-LLFHCSU2.js} +2 -2
- package/dist/{chunk-J5BA3BQ6.cjs → chunk-O7LUD7MH.cjs} +323 -3
- package/dist/chunk-O7LUD7MH.cjs.map +1 -0
- package/dist/{chunk-ILYFOJUN.js → chunk-OIBIRXRG.js} +3 -3
- package/dist/{chunk-FWEO3HSL.js → chunk-PQQF5KOW.js} +8 -8
- package/dist/{chunk-T6TV6HY6.cjs → chunk-PRSRYHQD.cjs} +36 -36
- package/dist/{chunk-T6TV6HY6.cjs.map → chunk-PRSRYHQD.cjs.map} +1 -1
- package/dist/chunk-Q6OUXEK3.cjs +150 -0
- package/dist/chunk-Q6OUXEK3.cjs.map +1 -0
- package/dist/{chunk-6GFRKLLS.cjs → chunk-QBWEH3IM.cjs} +429 -112
- package/dist/chunk-QBWEH3IM.cjs.map +1 -0
- package/dist/{chunk-ESIWZMMK.js → chunk-SYT2TLQF.js} +35 -37
- package/dist/{chunk-ESIWZMMK.js.map → chunk-SYT2TLQF.js.map} +1 -1
- package/dist/{chunk-YT3JL7YM.cjs → chunk-TLCTTQFF.cjs} +53 -53
- package/dist/{chunk-YT3JL7YM.cjs.map → chunk-TLCTTQFF.cjs.map} +1 -1
- package/dist/{chunk-P3RQ5UJE.cjs → chunk-UTQKC66X.cjs} +4 -4
- package/dist/{chunk-P3RQ5UJE.cjs.map → chunk-UTQKC66X.cjs.map} +1 -1
- package/dist/{chunk-J3B45HTA.cjs → chunk-XB25WOC2.cjs} +6 -6
- package/dist/{chunk-J3B45HTA.cjs.map → chunk-XB25WOC2.cjs.map} +1 -1
- package/dist/{chunk-YAFS2QFZ.cjs → chunk-XN2NBLV5.cjs} +313 -315
- package/dist/chunk-XN2NBLV5.cjs.map +1 -0
- package/dist/effects/index.d.cts +7 -4
- package/dist/effects/index.d.ts +7 -4
- package/dist/{export-DMeG6E06.d.ts → export-41rL6Cne.d.ts} +1 -1
- package/dist/{export-AZSwX087.d.cts → export-CyJdfP_Z.d.cts} +5 -4
- package/dist/{export-KzubBKo7.d.cts → export-D9mXp05Q.d.cts} +1 -1
- package/dist/{export-BDkyDNM8.d.ts → export-DwnZ_hvQ.d.ts} +5 -4
- package/dist/extensions/index.cjs +3 -3
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.js +2 -2
- package/dist/generation/index.cjs +150 -945
- package/dist/generation/index.cjs.map +1 -1
- package/dist/generation/index.d.cts +3 -423
- package/dist/generation/index.d.ts +3 -423
- package/dist/generation/index.js +59 -854
- package/dist/generation/index.js.map +1 -1
- package/dist/grammar/index.cjs +3 -3
- package/dist/grammar/index.cjs.map +1 -1
- package/dist/grammar/index.js +2 -2
- package/dist/{helpers-Coa4e2j_.d.ts → helpers-C-RgeyvH.d.ts} +25 -8
- package/dist/{helpers-DHl28yLO.d.cts → helpers-v6GMazzg.d.cts} +25 -8
- package/dist/image-editor/index.cjs +986 -986
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +15 -11
- package/dist/image-editor/index.d.ts +15 -11
- package/dist/image-editor/index.js +94 -94
- package/dist/index.cjs +28 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +36 -36
- package/dist/{opentype-BWR7Qv8W.d.cts → opentype-KR_jj6b_.d.cts} +1 -1
- package/dist/{opentype-Dfcx6wFx.d.ts → opentype-a1KAW-qs.d.ts} +1 -1
- package/dist/paint/index.cjs +5 -8
- package/dist/paint/index.cjs.map +1 -1
- package/dist/paint/index.d.cts +4 -2
- package/dist/paint/index.d.ts +4 -2
- package/dist/paint/index.js +15 -18
- package/dist/paint-editor/index.cjs +405 -403
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +15 -748
- package/dist/paint-editor/index.d.ts +15 -748
- package/dist/paint-editor/index.js +79 -77
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/{pathfinder-D8KQ6blQ.d.cts → pathfinder-BHS4vQNm.d.cts} +1 -1
- package/dist/{pathfinder-Celbi3e6.d.ts → pathfinder-BVvTIBMo.d.ts} +1 -1
- package/dist/{pool-8JZGWHvR.d.ts → pool-CZQOrSXZ.d.ts} +1 -1
- package/dist/{pool-BfuxBKTd.d.cts → pool-FjZZmZ80.d.cts} +1 -1
- package/dist/provenance-DmlcgdzT.d.cts +426 -0
- package/dist/provenance-uh5r2TQ8.d.ts +426 -0
- package/dist/rand-8xbUb6ur.d.ts +1118 -0
- package/dist/rand-Cw9VLrVC.d.cts +1118 -0
- package/dist/raster/index.cjs +17 -19
- package/dist/raster/index.cjs.map +1 -1
- package/dist/raster/index.js +9 -11
- package/dist/raster/index.js.map +1 -1
- package/dist/{svg-CxxqG3_W.d.ts → svg-CSz3mzkw.d.ts} +2 -2
- package/dist/{svg-pwXWq6s2.d.cts → svg-DTb40ICU.d.cts} +2 -2
- package/dist/{tools-y1M6O3UT.d.ts → tools-B0wXP5cF.d.ts} +1 -1
- package/dist/{tools-3EBjR91b.d.cts → tools-Ca0kI1qo.d.cts} +1 -1
- package/dist/vector/index.cjs +2698 -1674
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +390 -72
- package/dist/vector/index.d.ts +390 -72
- package/dist/vector/index.js +1665 -641
- package/dist/vector/index.js.map +1 -1
- package/dist/video-editor/index.d.cts +7 -4
- package/dist/video-editor/index.d.ts +7 -4
- package/dist/{warp-Ceqdz7kj.d.cts → warp-DTOp0lON.d.cts} +1 -1
- package/dist/{warp-C1gwu2G_.d.ts → warp-pd7hrH4T.d.ts} +1 -1
- package/package.json +1 -1
- package/skills/pixerate-vector/SKILL.md +22 -0
- package/dist/brushstrokeRender-JNHVEUFG.cjs.map +0 -1
- package/dist/chunk-64PYNEHJ.js +0 -340
- package/dist/chunk-64PYNEHJ.js.map +0 -1
- package/dist/chunk-6GFRKLLS.cjs.map +0 -1
- package/dist/chunk-7QN76ESJ.js +0 -323
- package/dist/chunk-7QN76ESJ.js.map +0 -1
- package/dist/chunk-BR7EKQUP.js.map +0 -1
- package/dist/chunk-DCLJNVZS.cjs +0 -323
- package/dist/chunk-DCLJNVZS.cjs.map +0 -1
- package/dist/chunk-EM3FMJWE.js.map +0 -1
- package/dist/chunk-HHTCDFZC.js.map +0 -1
- package/dist/chunk-J5BA3BQ6.cjs.map +0 -1
- package/dist/chunk-YAFS2QFZ.cjs.map +0 -1
- package/dist/chunk-Z2H7KECK.cjs.map +0 -1
- package/dist/chunk-Z6OUCS2K.cjs +0 -340
- package/dist/chunk-Z6OUCS2K.cjs.map +0 -1
- package/dist/rand-BszBST4s.d.ts +0 -2140
- package/dist/rand-DOH_aMvm.d.cts +0 -2140
- /package/dist/{chunk-62XUO5LB.js.map → chunk-3X6IAJUQ.js.map} +0 -0
- /package/dist/{chunk-7RJ6P7MI.js.map → chunk-6S6362D2.js.map} +0 -0
- /package/dist/{chunk-SVYE5HIM.js.map → chunk-EQQMGO42.js.map} +0 -0
- /package/dist/{chunk-OXSV64JX.js.map → chunk-G6IKY6PL.js.map} +0 -0
- /package/dist/{chunk-UYQUPUR6.js.map → chunk-HUO3TI4C.js.map} +0 -0
- /package/dist/{chunk-2HC4DRF4.js.map → chunk-LLFHCSU2.js.map} +0 -0
- /package/dist/{chunk-ILYFOJUN.js.map → chunk-OIBIRXRG.js.map} +0 -0
- /package/dist/{chunk-FWEO3HSL.js.map → chunk-PQQF5KOW.js.map} +0 -0
|
@@ -0,0 +1,727 @@
|
|
|
1
|
+
// src/generation/capabilities.ts
|
|
2
|
+
var REFERENCE_ROLE_NAME_REGEX = /^[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9])?$/;
|
|
3
|
+
function isReferenceRoleName(value) {
|
|
4
|
+
return typeof value === "string" && value.length <= 64 && REFERENCE_ROLE_NAME_REGEX.test(value);
|
|
5
|
+
}
|
|
6
|
+
var REFERENCE_ROLES = [
|
|
7
|
+
"start_frame",
|
|
8
|
+
"end_frame",
|
|
9
|
+
"style_ref",
|
|
10
|
+
"character_ref",
|
|
11
|
+
"background_ref",
|
|
12
|
+
"mask",
|
|
13
|
+
"image_ref",
|
|
14
|
+
"video_ref",
|
|
15
|
+
"audio_ref"
|
|
16
|
+
];
|
|
17
|
+
var REFERENCE_ROLE_LABELS = {
|
|
18
|
+
start_frame: "Start frame",
|
|
19
|
+
end_frame: "End frame",
|
|
20
|
+
style_ref: "Style reference",
|
|
21
|
+
character_ref: "Character reference",
|
|
22
|
+
background_ref: "Background reference",
|
|
23
|
+
mask: "Mask",
|
|
24
|
+
image_ref: "Image reference",
|
|
25
|
+
video_ref: "Video reference",
|
|
26
|
+
audio_ref: "Audio reference"
|
|
27
|
+
};
|
|
28
|
+
var REFERENCE_ROLE_ALIASES = {
|
|
29
|
+
reference: "image_ref",
|
|
30
|
+
image: "image_ref",
|
|
31
|
+
style: "style_ref",
|
|
32
|
+
character: "character_ref",
|
|
33
|
+
background: "background_ref",
|
|
34
|
+
"start-frame": "start_frame",
|
|
35
|
+
"first-frame": "start_frame",
|
|
36
|
+
first_frame: "start_frame",
|
|
37
|
+
"end-frame": "end_frame",
|
|
38
|
+
"last-frame": "end_frame",
|
|
39
|
+
last_frame: "end_frame",
|
|
40
|
+
"style-ref": "style_ref",
|
|
41
|
+
"character-ref": "character_ref",
|
|
42
|
+
"background-ref": "background_ref",
|
|
43
|
+
"image-ref": "image_ref",
|
|
44
|
+
"video-ref": "video_ref",
|
|
45
|
+
"audio-ref": "audio_ref",
|
|
46
|
+
video: "video_ref",
|
|
47
|
+
audio: "audio_ref"
|
|
48
|
+
};
|
|
49
|
+
var isBuiltinRole = (role) => REFERENCE_ROLES.includes(role);
|
|
50
|
+
function referenceRoleLabel(role, caps) {
|
|
51
|
+
const declared = caps?.references?.roles[role]?.label;
|
|
52
|
+
if (declared) return declared;
|
|
53
|
+
if (isBuiltinRole(role)) return REFERENCE_ROLE_LABELS[role];
|
|
54
|
+
const words = String(role).replace(/[_-]+/g, " ").trim();
|
|
55
|
+
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
56
|
+
}
|
|
57
|
+
function normalizeReferenceRole(role, caps) {
|
|
58
|
+
const name = String(role).trim();
|
|
59
|
+
if (caps ? !!caps.references?.roles[name] : isBuiltinRole(name)) return name;
|
|
60
|
+
const lower = name.toLowerCase();
|
|
61
|
+
if (caps?.references?.roles[lower]) return lower;
|
|
62
|
+
if (!caps && isBuiltinRole(lower)) return lower;
|
|
63
|
+
return REFERENCE_ROLE_ALIASES[lower] ?? (isBuiltinRole(lower) ? lower : name);
|
|
64
|
+
}
|
|
65
|
+
function mediaTypeMatches(mediaType, accepts) {
|
|
66
|
+
if (!accepts || accepts.length === 0) return true;
|
|
67
|
+
if (!mediaType) return false;
|
|
68
|
+
const type = mediaType.split(";")[0].trim().toLowerCase();
|
|
69
|
+
const kind = type.split("/")[0];
|
|
70
|
+
return accepts.some((entry) => {
|
|
71
|
+
const pattern = entry.trim().toLowerCase();
|
|
72
|
+
if (pattern === "*" || pattern === "*/*" || pattern === type) return true;
|
|
73
|
+
if (!pattern.includes("/")) return pattern === kind;
|
|
74
|
+
if (pattern.endsWith("/*")) return pattern.slice(0, -2) === kind;
|
|
75
|
+
return false;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
var GENERATION_REQUEST_FIELDS = [
|
|
79
|
+
"model",
|
|
80
|
+
"prompt",
|
|
81
|
+
"negativePrompt",
|
|
82
|
+
"systemPrompt",
|
|
83
|
+
"aspectRatio",
|
|
84
|
+
"resolution",
|
|
85
|
+
"quality",
|
|
86
|
+
"count",
|
|
87
|
+
"duration",
|
|
88
|
+
"seed",
|
|
89
|
+
"mode",
|
|
90
|
+
"references",
|
|
91
|
+
"params"
|
|
92
|
+
];
|
|
93
|
+
function textFieldCapability(value) {
|
|
94
|
+
if (!value) return null;
|
|
95
|
+
return value === true ? {} : value;
|
|
96
|
+
}
|
|
97
|
+
function seedCapability(value) {
|
|
98
|
+
if (!value) return null;
|
|
99
|
+
return value === true ? {} : value;
|
|
100
|
+
}
|
|
101
|
+
function supportedReferenceRoles(caps) {
|
|
102
|
+
const roles = caps.references?.roles ?? {};
|
|
103
|
+
const builtin = REFERENCE_ROLES.filter((role) => (roles[role]?.max ?? 0) > 0);
|
|
104
|
+
const custom = Object.keys(roles).filter(
|
|
105
|
+
(role) => !isBuiltinRole(role) && isReferenceRoleName(role) && (roles[role]?.max ?? 0) > 0
|
|
106
|
+
);
|
|
107
|
+
return [...builtin, ...custom];
|
|
108
|
+
}
|
|
109
|
+
function supportedModes(caps) {
|
|
110
|
+
const modes = ["generate"];
|
|
111
|
+
if (caps.editing) modes.push("edit");
|
|
112
|
+
if (caps.inpainting) modes.push("inpaint");
|
|
113
|
+
return modes;
|
|
114
|
+
}
|
|
115
|
+
var PRESENTATION_KEYS = ["name", "description", "badges", "icon", "group"];
|
|
116
|
+
function mergeCapabilities(remote, overlay = []) {
|
|
117
|
+
const overlayById = new Map(overlay.map((entry) => [entry.id, entry]));
|
|
118
|
+
const remoteIds = new Set(remote.map((model) => model.id));
|
|
119
|
+
const merged = remote.map((model) => {
|
|
120
|
+
const extra = overlayById.get(model.id);
|
|
121
|
+
if (!extra) return { ...model };
|
|
122
|
+
const next = { ...model };
|
|
123
|
+
for (const key of PRESENTATION_KEYS) {
|
|
124
|
+
if (extra[key] !== void 0) next[key] = extra[key];
|
|
125
|
+
}
|
|
126
|
+
return next;
|
|
127
|
+
});
|
|
128
|
+
for (const entry of overlay) {
|
|
129
|
+
if (remoteIds.has(entry.id) || !entry.media) continue;
|
|
130
|
+
remoteIds.add(entry.id);
|
|
131
|
+
merged.push({ ...entry });
|
|
132
|
+
}
|
|
133
|
+
return merged;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/generation/plan.ts
|
|
137
|
+
var EPSILON = 1e-9;
|
|
138
|
+
function aspectRatioRank(value) {
|
|
139
|
+
const match = /^\s*(\d+(?:\.\d+)?)\s*[:x/×]\s*(\d+(?:\.\d+)?)\s*$/i.exec(String(value));
|
|
140
|
+
if (!match) return void 0;
|
|
141
|
+
const w = Number(match[1]);
|
|
142
|
+
const h = Number(match[2]);
|
|
143
|
+
if (!(w > 0) || !(h > 0)) return void 0;
|
|
144
|
+
return Math.log(w / h);
|
|
145
|
+
}
|
|
146
|
+
function resolutionRank(value) {
|
|
147
|
+
const text = String(value).trim().toLowerCase();
|
|
148
|
+
let pixels;
|
|
149
|
+
let match = /^(\d+(?:\.\d+)?)\s*[x×*]\s*(\d+(?:\.\d+)?)$/.exec(text);
|
|
150
|
+
if (match) pixels = Number(match[1]) * Number(match[2]);
|
|
151
|
+
else if (match = /^(\d+(?:\.\d+)?)p$/.exec(text)) pixels = Number(match[1]) ** 2 * 16 / 9;
|
|
152
|
+
else if (match = /^(\d+(?:\.\d+)?)k$/.exec(text)) pixels = (Number(match[1]) * 1024) ** 2;
|
|
153
|
+
return pixels && pixels > 0 ? Math.log(pixels) : void 0;
|
|
154
|
+
}
|
|
155
|
+
function resolutionMegapixels(value) {
|
|
156
|
+
const rank = resolutionRank(value);
|
|
157
|
+
return rank === void 0 ? void 0 : Math.exp(rank) / 1e6;
|
|
158
|
+
}
|
|
159
|
+
var QUALITY_LADDER = {
|
|
160
|
+
draft: 0,
|
|
161
|
+
preview: 0,
|
|
162
|
+
low: 1,
|
|
163
|
+
fast: 1,
|
|
164
|
+
turbo: 1,
|
|
165
|
+
standard: 2,
|
|
166
|
+
normal: 2,
|
|
167
|
+
medium: 2,
|
|
168
|
+
balanced: 2,
|
|
169
|
+
high: 3,
|
|
170
|
+
hd: 3,
|
|
171
|
+
quality: 3,
|
|
172
|
+
ultra: 4,
|
|
173
|
+
max: 5,
|
|
174
|
+
best: 5
|
|
175
|
+
};
|
|
176
|
+
function qualityRank(value) {
|
|
177
|
+
return QUALITY_LADDER[String(value).trim().toLowerCase()];
|
|
178
|
+
}
|
|
179
|
+
var numberRank = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
180
|
+
function snapToOption(value, options, rank, tie) {
|
|
181
|
+
const target = rank(value);
|
|
182
|
+
if (target === void 0) return void 0;
|
|
183
|
+
let best;
|
|
184
|
+
for (const option of options) {
|
|
185
|
+
const r = rank(option);
|
|
186
|
+
if (r === void 0) continue;
|
|
187
|
+
const distance = Math.abs(r - target);
|
|
188
|
+
if (!best || distance < best.distance - EPSILON || Math.abs(distance - best.distance) <= EPSILON && (tie === "lower" ? r < best.rank : r > best.rank)) {
|
|
189
|
+
best = { option, distance, rank: r };
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return best?.option;
|
|
193
|
+
}
|
|
194
|
+
function truncateText(text, max) {
|
|
195
|
+
if (text.length <= max) return text;
|
|
196
|
+
let end = max;
|
|
197
|
+
const code = text.charCodeAt(end - 1);
|
|
198
|
+
if (end > 0 && code >= 55296 && code <= 56319) end -= 1;
|
|
199
|
+
return text.slice(0, end);
|
|
200
|
+
}
|
|
201
|
+
function cloneRequest(request) {
|
|
202
|
+
const copy = { ...request };
|
|
203
|
+
if (request.references) copy.references = request.references.map((ref) => ({ ...ref }));
|
|
204
|
+
if (request.params) copy.params = { ...request.params };
|
|
205
|
+
return copy;
|
|
206
|
+
}
|
|
207
|
+
var describe = (value) => typeof value === "string" ? `"${value}"` : JSON.stringify(value);
|
|
208
|
+
var list = (options) => options.map(describe).join(", ");
|
|
209
|
+
var Planner = class {
|
|
210
|
+
constructor(caps, request, options, strategy) {
|
|
211
|
+
this.caps = caps;
|
|
212
|
+
this.request = request;
|
|
213
|
+
this.options = options;
|
|
214
|
+
this.strategy = strategy;
|
|
215
|
+
this.tie = strategy === "downgrade" ? "lower" : "higher";
|
|
216
|
+
this.strict = strategy === "error";
|
|
217
|
+
}
|
|
218
|
+
caps;
|
|
219
|
+
request;
|
|
220
|
+
options;
|
|
221
|
+
strategy;
|
|
222
|
+
adjustments = [];
|
|
223
|
+
errors = [];
|
|
224
|
+
tie;
|
|
225
|
+
strict;
|
|
226
|
+
adjust(field, from, to, kind, reason) {
|
|
227
|
+
this.adjustments.push({ field, from, to, kind, reason });
|
|
228
|
+
}
|
|
229
|
+
error(field, value, message) {
|
|
230
|
+
this.errors.push({ field, value, message });
|
|
231
|
+
}
|
|
232
|
+
/** Removes an unsupported field (or reports it under `error`). */
|
|
233
|
+
unsupported(field, message) {
|
|
234
|
+
const value = this.request[field];
|
|
235
|
+
if (this.strict) {
|
|
236
|
+
this.error(field, value, message);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
delete this.request[field];
|
|
240
|
+
this.adjust(field, value, void 0, "dropped", message);
|
|
241
|
+
}
|
|
242
|
+
defaulted(field, value, set) {
|
|
243
|
+
if (!this.options.fillDefaults || value === void 0) return;
|
|
244
|
+
set();
|
|
245
|
+
this.adjust(field, void 0, value, "defaulted", "Filled with the model default.");
|
|
246
|
+
}
|
|
247
|
+
planText(field, maxLength, measured) {
|
|
248
|
+
const value = this.request[field];
|
|
249
|
+
if (value === void 0 || maxLength === void 0) return;
|
|
250
|
+
if (typeof value !== "string") {
|
|
251
|
+
this.error(field, value, `Expected text.`);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const text = measured ?? value;
|
|
255
|
+
if (text.length <= maxLength) return;
|
|
256
|
+
if (this.strict || measured !== void 0) {
|
|
257
|
+
this.error(
|
|
258
|
+
field,
|
|
259
|
+
text.length,
|
|
260
|
+
`${measured !== void 0 ? "Resolved text" : "Text"} is ${text.length} characters; the model accepts at most ${maxLength}.`
|
|
261
|
+
);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const next = truncateText(value, maxLength);
|
|
265
|
+
this.request[field] = next;
|
|
266
|
+
this.adjust(field, value.length, next.length, "truncated", `Truncated to the model's ${maxLength}-character limit.`);
|
|
267
|
+
}
|
|
268
|
+
planEnum(field, cap, rank, label) {
|
|
269
|
+
const value = this.request[field];
|
|
270
|
+
if (value === void 0) {
|
|
271
|
+
if (cap) this.defaulted(field, cap.default, () => this.request[field] = cap.default);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
if (!cap || cap.options.length === 0) {
|
|
275
|
+
this.unsupported(field, `The model does not take a ${label}.`);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
if (cap.options.includes(value)) return;
|
|
279
|
+
if (this.strict) {
|
|
280
|
+
this.error(field, value, `${describe(value)} is not a supported ${label}; supported: ${list(cap.options)}.`);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const snapped = snapToOption(value, cap.options, rank, this.tie);
|
|
284
|
+
const next = snapped ?? cap.default ?? cap.options[0];
|
|
285
|
+
this.request[field] = next;
|
|
286
|
+
this.adjust(
|
|
287
|
+
field,
|
|
288
|
+
value,
|
|
289
|
+
next,
|
|
290
|
+
"snapped",
|
|
291
|
+
snapped !== void 0 ? `${describe(value)} is not supported; using the nearest ${label}.` : `${describe(value)} is not supported; using ${cap.default !== void 0 ? "the default" : "the first option"}.`
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
/** Clamps/rounds/snaps a number. Returns the next value or `undefined` after an error. */
|
|
295
|
+
planNumber(field, value, spec, label) {
|
|
296
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
297
|
+
this.error(field, value, `Expected a number for ${label}.`);
|
|
298
|
+
return void 0;
|
|
299
|
+
}
|
|
300
|
+
const options = spec.options?.filter(
|
|
301
|
+
(o) => (spec.min === void 0 || o >= spec.min) && (spec.max === void 0 || o <= spec.max)
|
|
302
|
+
);
|
|
303
|
+
if (options && options.length > 0) {
|
|
304
|
+
if (options.includes(value)) return { value, changed: false };
|
|
305
|
+
if (this.strict) {
|
|
306
|
+
this.error(field, value, `${value} is not a supported ${label}; supported: ${list(options)}.`);
|
|
307
|
+
return void 0;
|
|
308
|
+
}
|
|
309
|
+
const next2 = snapToOption(value, options, numberRank, this.tie);
|
|
310
|
+
this.adjust(field, value, next2, "snapped", `${value} is not supported; using the nearest ${label}.`);
|
|
311
|
+
return { value: next2, changed: true };
|
|
312
|
+
}
|
|
313
|
+
let next = value;
|
|
314
|
+
if (spec.step !== void 0 && spec.step > 0) {
|
|
315
|
+
const base = spec.min ?? 0;
|
|
316
|
+
const steps = (next - base) / spec.step;
|
|
317
|
+
const rounded = Math.abs(steps - Math.trunc(steps) - 0.5) < EPSILON ? this.tie === "lower" ? Math.floor(steps) : Math.ceil(steps) : Math.round(steps);
|
|
318
|
+
next = Number((base + rounded * spec.step).toPrecision(12));
|
|
319
|
+
}
|
|
320
|
+
if (spec.integer && !Number.isInteger(next)) {
|
|
321
|
+
const frac = next - Math.floor(next);
|
|
322
|
+
next = Math.abs(frac - 0.5) < EPSILON ? this.tie === "lower" ? Math.floor(next) : Math.ceil(next) : Math.round(next);
|
|
323
|
+
}
|
|
324
|
+
let kind = "snapped";
|
|
325
|
+
if (spec.min !== void 0 && next < spec.min) {
|
|
326
|
+
next = spec.min;
|
|
327
|
+
kind = "clamped";
|
|
328
|
+
}
|
|
329
|
+
if (spec.max !== void 0 && next > spec.max) {
|
|
330
|
+
next = spec.max;
|
|
331
|
+
kind = "clamped";
|
|
332
|
+
}
|
|
333
|
+
if (next === value) return { value, changed: false };
|
|
334
|
+
const range = `${spec.min ?? "-\u221E"}\u2013${spec.max ?? "\u221E"}`;
|
|
335
|
+
if (this.strict) {
|
|
336
|
+
this.error(
|
|
337
|
+
field,
|
|
338
|
+
value,
|
|
339
|
+
kind === "clamped" ? `${label} must be within ${range}.` : `${value} is not a valid ${label} (try ${next}).`
|
|
340
|
+
);
|
|
341
|
+
return void 0;
|
|
342
|
+
}
|
|
343
|
+
this.adjust(
|
|
344
|
+
field,
|
|
345
|
+
value,
|
|
346
|
+
next,
|
|
347
|
+
kind,
|
|
348
|
+
kind === "clamped" ? `Clamped to the supported range ${range}.` : `Rounded to a supported ${label}.`
|
|
349
|
+
);
|
|
350
|
+
return { value: next, changed: true };
|
|
351
|
+
}
|
|
352
|
+
planCount() {
|
|
353
|
+
const value = this.request.count;
|
|
354
|
+
const cap = this.caps.count;
|
|
355
|
+
if (value === void 0) {
|
|
356
|
+
if (cap) this.defaulted("count", cap.default, () => this.request.count = cap.default);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (!cap) {
|
|
360
|
+
if (value === 1) return;
|
|
361
|
+
this.unsupported("count", "The model produces one output per request.");
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
const result = this.planNumber("count", value, { min: 1, max: cap.max, integer: true, options: cap.options }, "output count");
|
|
365
|
+
if (result) this.request.count = result.value;
|
|
366
|
+
}
|
|
367
|
+
planDuration() {
|
|
368
|
+
const value = this.request.duration;
|
|
369
|
+
const cap = this.caps.duration;
|
|
370
|
+
if (value === void 0) {
|
|
371
|
+
if (cap) this.defaulted("duration", cap.default, () => this.request.duration = cap.default);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
if (!cap) {
|
|
375
|
+
this.unsupported("duration", "The model does not take a duration.");
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const result = this.planNumber("duration", value, cap, "duration");
|
|
379
|
+
if (result) this.request.duration = result.value;
|
|
380
|
+
}
|
|
381
|
+
planSeed() {
|
|
382
|
+
const value = this.request.seed;
|
|
383
|
+
if (value === void 0) return;
|
|
384
|
+
const cap = seedCapability(this.caps.seed);
|
|
385
|
+
if (!cap) {
|
|
386
|
+
this.unsupported("seed", "The model does not take a seed.");
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const result = this.planNumber("seed", value, { ...cap, integer: true }, "seed");
|
|
390
|
+
if (result) this.request.seed = result.value;
|
|
391
|
+
}
|
|
392
|
+
planMode() {
|
|
393
|
+
const mode = this.request.mode;
|
|
394
|
+
if (mode === void 0) return;
|
|
395
|
+
const modes = supportedModes(this.caps);
|
|
396
|
+
if (!modes.includes(mode)) {
|
|
397
|
+
this.error("mode", mode, `The model does not support ${describe(mode)}; supported: ${list(modes)}.`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
roleCapability(role) {
|
|
401
|
+
const cap = this.caps.references?.roles[role];
|
|
402
|
+
if (cap && cap.max > 0) return cap;
|
|
403
|
+
if (role === "mask" && this.caps.inpainting) return { max: 1 };
|
|
404
|
+
return void 0;
|
|
405
|
+
}
|
|
406
|
+
/** Turns `options.mentions` into references (appended after the request's own). */
|
|
407
|
+
addMentions() {
|
|
408
|
+
const mentions = this.options.mentions;
|
|
409
|
+
if (!mentions?.length) return;
|
|
410
|
+
const refs = [...this.request.references ?? []];
|
|
411
|
+
for (const mention of mentions) {
|
|
412
|
+
if (!mention || typeof mention.id !== "string" || mention.id === "") continue;
|
|
413
|
+
let role = mention.role ?? void 0;
|
|
414
|
+
if (!role) {
|
|
415
|
+
role = this.options.defaultMentionRole ?? this.inferRole(mention.mediaType);
|
|
416
|
+
this.adjust(
|
|
417
|
+
`references.${role}`,
|
|
418
|
+
void 0,
|
|
419
|
+
role,
|
|
420
|
+
"defaulted",
|
|
421
|
+
`@${mention.label ?? mention.id} has no role; using ${role}.`
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
refs.push({
|
|
425
|
+
id: mention.id,
|
|
426
|
+
role,
|
|
427
|
+
...mention.url !== void 0 ? { url: mention.url } : {},
|
|
428
|
+
...mention.mediaType !== void 0 ? { mediaType: mention.mediaType } : {},
|
|
429
|
+
...mention.contentHash !== void 0 ? { contentHash: mention.contentHash } : {}
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
this.request.references = refs;
|
|
433
|
+
}
|
|
434
|
+
/** First role of the model (other than `mask`) whose `accepts` matches `mediaType`. */
|
|
435
|
+
inferRole(mediaType) {
|
|
436
|
+
for (const role of supportedReferenceRoles(this.caps)) {
|
|
437
|
+
if (role === "mask") continue;
|
|
438
|
+
const cap = this.roleCapability(role);
|
|
439
|
+
if (cap && (mediaType === void 0 || mediaTypeMatches(mediaType, cap.accepts))) return role;
|
|
440
|
+
}
|
|
441
|
+
return "image_ref";
|
|
442
|
+
}
|
|
443
|
+
planReferences() {
|
|
444
|
+
const refs = this.request.references;
|
|
445
|
+
const allowDrop = !this.strict && (this.options.dropUnsupportedReferences ?? (this.strategy === "nearest" || this.strategy === "downgrade"));
|
|
446
|
+
const byRole = /* @__PURE__ */ new Map();
|
|
447
|
+
const kept = [];
|
|
448
|
+
const unsupported = /* @__PURE__ */ new Map();
|
|
449
|
+
for (const [index, original] of (refs ?? []).entries()) {
|
|
450
|
+
let ref = original;
|
|
451
|
+
if (!ref || typeof ref.id !== "string" || ref.id === "" || !isReferenceRoleName(ref.role)) {
|
|
452
|
+
this.error(`references.${index}`, ref, "Each reference needs an `id` and a valid `role`.");
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
if (!this.roleCapability(ref.role)) {
|
|
456
|
+
const alias = normalizeReferenceRole(ref.role, this.caps);
|
|
457
|
+
if (alias !== ref.role && this.roleCapability(alias)) {
|
|
458
|
+
if (this.strict) {
|
|
459
|
+
this.error(`references.${ref.role}`, ref.role, `The model calls this role ${describe(alias)}.`);
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
this.adjust(
|
|
463
|
+
`references.${ref.role}`,
|
|
464
|
+
ref.role,
|
|
465
|
+
alias,
|
|
466
|
+
"snapped",
|
|
467
|
+
`Using the model's ${alias} role for ${describe(ref.role)}.`
|
|
468
|
+
);
|
|
469
|
+
ref = { ...ref, role: alias };
|
|
470
|
+
} else {
|
|
471
|
+
unsupported.set(ref.role, (unsupported.get(ref.role) ?? 0) + 1);
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
const cap = this.roleCapability(ref.role);
|
|
476
|
+
if (ref.mediaType !== void 0 && !mediaTypeMatches(ref.mediaType, cap.accepts)) {
|
|
477
|
+
const message = `${describe(ref.id)} is ${describe(ref.mediaType)}; ${ref.role} accepts ${list(cap.accepts ?? [])}.`;
|
|
478
|
+
if (allowDrop) this.adjust(`references.${ref.role}`, ref.id, void 0, "dropped", message);
|
|
479
|
+
else this.error(`references.${ref.role}`, ref.id, message);
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
const group = byRole.get(ref.role) ?? [];
|
|
483
|
+
if (group.some((other) => other.id === ref.id)) {
|
|
484
|
+
this.adjust(`references.${ref.role}`, ref.id, void 0, "dropped", `Duplicate reference "${ref.id}" removed.`);
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
group.push(ref);
|
|
488
|
+
byRole.set(ref.role, group);
|
|
489
|
+
kept.push(ref);
|
|
490
|
+
}
|
|
491
|
+
for (const [role, count] of unsupported) {
|
|
492
|
+
const message = this.caps.media === "text" || !this.caps.references ? `The ${this.caps.media} model "${this.caps.id}" does not accept reference inputs (${role}).` : `The model does not accept ${role} references.`;
|
|
493
|
+
if (allowDrop) this.adjust(`references.${role}`, count, 0, "dropped", message);
|
|
494
|
+
else this.error(`references.${role}`, count, message);
|
|
495
|
+
}
|
|
496
|
+
const removed = /* @__PURE__ */ new Set();
|
|
497
|
+
const custom = supportedReferenceRoles(this.caps).filter(
|
|
498
|
+
(role) => !REFERENCE_ROLES.includes(role)
|
|
499
|
+
);
|
|
500
|
+
for (const role of [...REFERENCE_ROLES, ...custom]) {
|
|
501
|
+
const cap = this.roleCapability(role);
|
|
502
|
+
const group = byRole.get(role) ?? [];
|
|
503
|
+
if (!cap) continue;
|
|
504
|
+
if (group.length > cap.max) {
|
|
505
|
+
if (this.strict) {
|
|
506
|
+
this.error(`references.${role}`, group.length, `At most ${cap.max} ${role} reference(s) are supported.`);
|
|
507
|
+
} else {
|
|
508
|
+
group.slice(cap.max).forEach((ref) => removed.add(ref));
|
|
509
|
+
this.adjust(
|
|
510
|
+
`references.${role}`,
|
|
511
|
+
group.length,
|
|
512
|
+
cap.max,
|
|
513
|
+
"truncated",
|
|
514
|
+
`Kept the first ${cap.max} ${role} reference(s); the model accepts no more.`
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
if (cap.min !== void 0 && group.length < cap.min) {
|
|
519
|
+
this.error(`references.${role}`, group.length, `At least ${cap.min} ${role} reference(s) are required.`);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
let next = kept.filter((ref) => !removed.has(ref));
|
|
523
|
+
const maxTotal = this.caps.references?.maxTotal;
|
|
524
|
+
if (maxTotal !== void 0 && next.length > maxTotal) {
|
|
525
|
+
if (this.strict) {
|
|
526
|
+
this.error("references", next.length, `At most ${maxTotal} references are supported in total.`);
|
|
527
|
+
} else {
|
|
528
|
+
this.adjust(
|
|
529
|
+
"references",
|
|
530
|
+
next.length,
|
|
531
|
+
maxTotal,
|
|
532
|
+
"truncated",
|
|
533
|
+
`Kept the first ${maxTotal} references; the model accepts no more in total.`
|
|
534
|
+
);
|
|
535
|
+
next = next.slice(0, maxTotal);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
if (this.request.mode === "inpaint" && !next.some((ref) => ref.role === "mask")) {
|
|
539
|
+
this.error("references.mask", 0, "Inpainting needs a `mask` reference.");
|
|
540
|
+
}
|
|
541
|
+
if (refs === void 0) return;
|
|
542
|
+
if (!this.strict) {
|
|
543
|
+
if (next.length > 0) this.request.references = next;
|
|
544
|
+
else delete this.request.references;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
planParam(name, spec, value) {
|
|
548
|
+
const field = `params.${name}`;
|
|
549
|
+
if (!spec) {
|
|
550
|
+
if (this.strict) this.error(field, value, `Unknown parameter "${name}".`);
|
|
551
|
+
else this.adjust(field, value, void 0, "dropped", `The model has no "${name}" parameter.`);
|
|
552
|
+
return void 0;
|
|
553
|
+
}
|
|
554
|
+
const label = spec.label ?? name;
|
|
555
|
+
if (spec.type === "boolean") {
|
|
556
|
+
if (typeof value !== "boolean") this.error(field, value, `Expected true or false for ${label}.`);
|
|
557
|
+
return value;
|
|
558
|
+
}
|
|
559
|
+
if (spec.type === "enum") {
|
|
560
|
+
if (spec.options.includes(value)) return value;
|
|
561
|
+
if (this.strict) {
|
|
562
|
+
this.error(field, value, `${describe(value)} is not a supported ${label}; supported: ${list(spec.options)}.`);
|
|
563
|
+
return value;
|
|
564
|
+
}
|
|
565
|
+
const numeric = spec.options.every((o) => typeof o === "number");
|
|
566
|
+
const snapped = numeric ? snapToOption(value, spec.options, numberRank, this.tie) : void 0;
|
|
567
|
+
const next = snapped ?? spec.default ?? spec.options[0];
|
|
568
|
+
this.adjust(
|
|
569
|
+
field,
|
|
570
|
+
value,
|
|
571
|
+
next,
|
|
572
|
+
"snapped",
|
|
573
|
+
snapped !== void 0 ? `Using the nearest supported ${label}.` : `${describe(value)} is not supported; using ${spec.default !== void 0 ? "the default" : "the first option"}.`
|
|
574
|
+
);
|
|
575
|
+
return next;
|
|
576
|
+
}
|
|
577
|
+
const result = this.planNumber(field, value, { ...spec, integer: spec.type === "integer" }, label);
|
|
578
|
+
return result ? result.value : value;
|
|
579
|
+
}
|
|
580
|
+
planParams() {
|
|
581
|
+
const params = this.request.params;
|
|
582
|
+
const specs = this.caps.params ?? {};
|
|
583
|
+
const next = {};
|
|
584
|
+
for (const [name, value] of Object.entries(params ?? {})) {
|
|
585
|
+
if (value === void 0) continue;
|
|
586
|
+
const planned = this.planParam(name, specs[name], value);
|
|
587
|
+
if (planned !== void 0) next[name] = planned;
|
|
588
|
+
else if (this.strict) next[name] = value;
|
|
589
|
+
}
|
|
590
|
+
if (this.options.fillDefaults) {
|
|
591
|
+
for (const [name, spec] of Object.entries(specs)) {
|
|
592
|
+
if (next[name] === void 0 && spec.default !== void 0) {
|
|
593
|
+
next[name] = spec.default;
|
|
594
|
+
this.adjust(`params.${name}`, void 0, spec.default, "defaulted", "Filled with the model default.");
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
if (Object.keys(next).length > 0) this.request.params = next;
|
|
599
|
+
else delete this.request.params;
|
|
600
|
+
}
|
|
601
|
+
run() {
|
|
602
|
+
const { caps, request } = this;
|
|
603
|
+
for (const key of Object.keys(request)) {
|
|
604
|
+
if (GENERATION_REQUEST_FIELDS.includes(key)) continue;
|
|
605
|
+
const value = request[key];
|
|
606
|
+
if (this.strict) this.error(key, value, `Unknown request field "${key}".`);
|
|
607
|
+
else {
|
|
608
|
+
delete request[key];
|
|
609
|
+
this.adjust(key, value, void 0, "dropped", `Unknown request field "${key}".`);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
if (request.model !== void 0 && request.model !== caps.id) {
|
|
613
|
+
this.error("model", request.model, `The request targets "${request.model}" but the plan is for "${caps.id}".`);
|
|
614
|
+
}
|
|
615
|
+
request.model = caps.id;
|
|
616
|
+
const promptCap = caps.prompt ?? {};
|
|
617
|
+
if (promptCap.required && !(request.prompt ?? "").trim()) {
|
|
618
|
+
this.error("prompt", request.prompt, "A prompt is required.");
|
|
619
|
+
}
|
|
620
|
+
const countResolved = promptCap.countResolved ?? true;
|
|
621
|
+
const measured = countResolved && this.options.resolvedPrompt !== void 0 && this.options.resolvedPrompt !== request.prompt ? this.options.resolvedPrompt : void 0;
|
|
622
|
+
this.planText("prompt", promptCap.maxLength, measured);
|
|
623
|
+
for (const field of ["negativePrompt", "systemPrompt"]) {
|
|
624
|
+
if (request[field] === void 0) continue;
|
|
625
|
+
const cap = textFieldCapability(caps[field]);
|
|
626
|
+
if (!cap) {
|
|
627
|
+
this.unsupported(field, `The model does not take a ${field === "negativePrompt" ? "negative" : "system"} prompt.`);
|
|
628
|
+
continue;
|
|
629
|
+
}
|
|
630
|
+
this.planText(field, cap.maxLength);
|
|
631
|
+
}
|
|
632
|
+
this.planEnum("aspectRatio", caps.aspectRatios, aspectRatioRank, "aspect ratio");
|
|
633
|
+
this.planEnum("resolution", caps.resolutions, resolutionRank, "resolution");
|
|
634
|
+
this.planEnum("quality", caps.quality, qualityRank, "quality");
|
|
635
|
+
this.planCount();
|
|
636
|
+
this.planDuration();
|
|
637
|
+
this.planSeed();
|
|
638
|
+
this.planMode();
|
|
639
|
+
this.addMentions();
|
|
640
|
+
this.planReferences();
|
|
641
|
+
this.planParams();
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
function planGenerationRequest(request, caps, options = {}) {
|
|
645
|
+
const strategy = options.strategy ?? "nearest";
|
|
646
|
+
const planner = new Planner(caps, cloneRequest(request ?? {}), options, strategy);
|
|
647
|
+
planner.run();
|
|
648
|
+
return {
|
|
649
|
+
ok: planner.errors.length === 0,
|
|
650
|
+
request: planner.request,
|
|
651
|
+
adjustments: planner.adjustments,
|
|
652
|
+
errors: planner.errors,
|
|
653
|
+
model: caps.id,
|
|
654
|
+
strategy
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// src/generation/hash.ts
|
|
659
|
+
function stableStringify(value) {
|
|
660
|
+
if (Array.isArray(value)) return `[${value.map((item) => item === void 0 ? "null" : stableStringify(item)).join(",")}]`;
|
|
661
|
+
if (value && typeof value === "object") {
|
|
662
|
+
const entries = Object.keys(value).filter((key) => value[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`);
|
|
663
|
+
return `{${entries.join(",")}}`;
|
|
664
|
+
}
|
|
665
|
+
return JSON.stringify(value) ?? "null";
|
|
666
|
+
}
|
|
667
|
+
var FNV_PRIME = 16777619;
|
|
668
|
+
function hashText(text) {
|
|
669
|
+
let a = 2166136261;
|
|
670
|
+
let b = 789454171;
|
|
671
|
+
for (let i = 0; i < text.length; i++) {
|
|
672
|
+
const unit = text.charCodeAt(i);
|
|
673
|
+
a = Math.imul(a ^ unit & 255, FNV_PRIME);
|
|
674
|
+
a = Math.imul(a ^ unit >>> 8, FNV_PRIME);
|
|
675
|
+
b = Math.imul(b ^ unit >>> 8, FNV_PRIME);
|
|
676
|
+
b = Math.imul(b ^ unit & 255, FNV_PRIME);
|
|
677
|
+
b ^= b >>> 15;
|
|
678
|
+
}
|
|
679
|
+
a ^= a >>> 16;
|
|
680
|
+
a = Math.imul(a, 2246822507);
|
|
681
|
+
a ^= a >>> 13;
|
|
682
|
+
b ^= b >>> 16;
|
|
683
|
+
b = Math.imul(b, 3266489909);
|
|
684
|
+
b ^= b >>> 13;
|
|
685
|
+
const hex = (n) => (n >>> 0).toString(16).padStart(8, "0");
|
|
686
|
+
return `h1-${hex(a)}${hex(b)}`;
|
|
687
|
+
}
|
|
688
|
+
function hashValue(value) {
|
|
689
|
+
return hashText(stableStringify(value));
|
|
690
|
+
}
|
|
691
|
+
var PRESENTATION_ONLY = /* @__PURE__ */ new Set(["name", "description", "badges", "icon", "group", "timing"]);
|
|
692
|
+
function hashCapabilities(caps) {
|
|
693
|
+
const relevant = {};
|
|
694
|
+
for (const key of Object.keys(caps)) {
|
|
695
|
+
if (!PRESENTATION_ONLY.has(key)) relevant[key] = caps[key];
|
|
696
|
+
}
|
|
697
|
+
return hashValue(relevant);
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
export {
|
|
701
|
+
REFERENCE_ROLE_NAME_REGEX,
|
|
702
|
+
isReferenceRoleName,
|
|
703
|
+
REFERENCE_ROLES,
|
|
704
|
+
REFERENCE_ROLE_LABELS,
|
|
705
|
+
REFERENCE_ROLE_ALIASES,
|
|
706
|
+
referenceRoleLabel,
|
|
707
|
+
normalizeReferenceRole,
|
|
708
|
+
mediaTypeMatches,
|
|
709
|
+
GENERATION_REQUEST_FIELDS,
|
|
710
|
+
textFieldCapability,
|
|
711
|
+
seedCapability,
|
|
712
|
+
supportedReferenceRoles,
|
|
713
|
+
supportedModes,
|
|
714
|
+
mergeCapabilities,
|
|
715
|
+
aspectRatioRank,
|
|
716
|
+
resolutionRank,
|
|
717
|
+
resolutionMegapixels,
|
|
718
|
+
QUALITY_LADDER,
|
|
719
|
+
qualityRank,
|
|
720
|
+
snapToOption,
|
|
721
|
+
planGenerationRequest,
|
|
722
|
+
stableStringify,
|
|
723
|
+
hashText,
|
|
724
|
+
hashValue,
|
|
725
|
+
hashCapabilities
|
|
726
|
+
};
|
|
727
|
+
//# sourceMappingURL=chunk-I52DRGGJ.js.map
|