@nodaro/prompts 1.54.0 → 1.55.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/{catalog-packs-DeMcSVCR.d.cts → catalog-packs-Bw7OpufR.d.cts} +1 -1
- package/dist/{catalog-packs-DjqvicAR.d.ts → catalog-packs-CyS8NdLM.d.ts} +1 -1
- package/dist/{chunk-HOZPYHRA.js → chunk-242NZ6SI.js} +5 -5
- package/dist/{chunk-HOZPYHRA.js.map → chunk-242NZ6SI.js.map} +1 -1
- package/dist/{chunk-56HWABF5.cjs → chunk-2LWYFWZL.cjs} +478 -2
- package/dist/chunk-2LWYFWZL.cjs.map +1 -0
- package/dist/{chunk-P4BXE4OA.cjs → chunk-2MTFPGQC.cjs} +13 -13
- package/dist/{chunk-P4BXE4OA.cjs.map → chunk-2MTFPGQC.cjs.map} +1 -1
- package/dist/{chunk-CDNW7O7H.cjs → chunk-32BMZ4Q5.cjs} +39 -39
- package/dist/{chunk-CDNW7O7H.cjs.map → chunk-32BMZ4Q5.cjs.map} +1 -1
- package/dist/{chunk-IVRSNUYX.js → chunk-4MCK7Y6C.js} +477 -3
- package/dist/chunk-4MCK7Y6C.js.map +1 -0
- package/dist/{chunk-FFPFBNXH.cjs → chunk-7ZWWJY24.cjs} +8 -2
- package/dist/chunk-7ZWWJY24.cjs.map +1 -0
- package/dist/{chunk-F22GZF7T.cjs → chunk-AMUXCE7X.cjs} +8 -8
- package/dist/{chunk-F22GZF7T.cjs.map → chunk-AMUXCE7X.cjs.map} +1 -1
- package/dist/{chunk-OQ3J7OGR.cjs → chunk-BHBZN2AP.cjs} +49 -49
- package/dist/{chunk-OQ3J7OGR.cjs.map → chunk-BHBZN2AP.cjs.map} +1 -1
- package/dist/{chunk-YAIPYPMM.js → chunk-BJGD4DBP.js} +4 -4
- package/dist/{chunk-YAIPYPMM.js.map → chunk-BJGD4DBP.js.map} +1 -1
- package/dist/{chunk-ZRORO6OM.js → chunk-CYYHQNW3.js} +4 -4
- package/dist/{chunk-ZRORO6OM.js.map → chunk-CYYHQNW3.js.map} +1 -1
- package/dist/{chunk-E5EKWWOO.cjs → chunk-FEHXLXAV.cjs} +8 -7
- package/dist/chunk-FEHXLXAV.cjs.map +1 -0
- package/dist/{chunk-5XPELUES.js → chunk-GJX5N63V.js} +8 -2
- package/dist/chunk-GJX5N63V.js.map +1 -0
- package/dist/{chunk-Z4KWM6DV.js → chunk-HZH6XXYK.js} +6 -6
- package/dist/{chunk-Z4KWM6DV.js.map → chunk-HZH6XXYK.js.map} +1 -1
- package/dist/{chunk-OMRFKG4M.js → chunk-KBWUO4P7.js} +3 -3
- package/dist/{chunk-OMRFKG4M.js.map → chunk-KBWUO4P7.js.map} +1 -1
- package/dist/{chunk-XUMEDRML.cjs → chunk-M25N26II.cjs} +8 -5
- package/dist/chunk-M25N26II.cjs.map +1 -0
- package/dist/{chunk-YDG3KMCN.js → chunk-NCF5TAR6.js} +8 -5
- package/dist/chunk-NCF5TAR6.js.map +1 -0
- package/dist/{chunk-NUC5RV4P.cjs → chunk-NDKJW7RP.cjs} +4 -4
- package/dist/{chunk-NUC5RV4P.cjs.map → chunk-NDKJW7RP.cjs.map} +1 -1
- package/dist/{chunk-ED47NNIN.js → chunk-OXNJVQ2V.js} +3 -3
- package/dist/{chunk-ED47NNIN.js.map → chunk-OXNJVQ2V.js.map} +1 -1
- package/dist/{chunk-PWYASBX2.cjs → chunk-P5HAPDV3.cjs} +18 -18
- package/dist/{chunk-PWYASBX2.cjs.map → chunk-P5HAPDV3.cjs.map} +1 -1
- package/dist/{chunk-EUU5W7XR.js → chunk-TMYYALRF.js} +4 -4
- package/dist/{chunk-EUU5W7XR.js.map → chunk-TMYYALRF.js.map} +1 -1
- package/dist/{chunk-H322GC7M.js → chunk-VX3BIUGY.js} +5 -4
- package/dist/chunk-VX3BIUGY.js.map +1 -0
- package/dist/{chunk-VBCVQPQ4.js → chunk-WDKQQ7WL.js} +3 -3
- package/dist/{chunk-VBCVQPQ4.js.map → chunk-WDKQQ7WL.js.map} +1 -1
- package/dist/{chunk-KTNCB2IE.cjs → chunk-XMRDZRGV.cjs} +35 -35
- package/dist/{chunk-KTNCB2IE.cjs.map → chunk-XMRDZRGV.cjs.map} +1 -1
- package/dist/{chunk-7BWDATUZ.cjs → chunk-Y3TSRO3S.cjs} +125 -125
- package/dist/{chunk-7BWDATUZ.cjs.map → chunk-Y3TSRO3S.cjs.map} +1 -1
- package/dist/entries/assembly.cjs +29 -29
- package/dist/entries/assembly.js +6 -6
- package/dist/entries/catalog-packs.d.cts +4 -4
- package/dist/entries/catalog-packs.d.ts +4 -4
- package/dist/entries/doctrine.cjs +46 -46
- package/dist/entries/doctrine.js +1 -1
- package/dist/entries/person.d.cts +3 -3
- package/dist/entries/person.d.ts +3 -3
- package/dist/entries/picker-art.cjs +22 -22
- package/dist/entries/picker-art.d.cts +1 -1
- package/dist/entries/picker-art.d.ts +1 -1
- package/dist/entries/picker-art.js +2 -2
- package/dist/entries/picker-catalogs.cjs +57 -57
- package/dist/entries/picker-catalogs.d.cts +3 -3
- package/dist/entries/picker-catalogs.d.ts +3 -3
- package/dist/entries/picker-catalogs.js +5 -5
- package/dist/entries/pickers.cjs +383 -383
- package/dist/entries/pickers.js +3 -3
- package/dist/entries/presets.cjs +46 -38
- package/dist/entries/presets.d.cts +13 -1
- package/dist/entries/presets.d.ts +13 -1
- package/dist/entries/presets.js +1 -1
- package/dist/entries/prompt-builder.cjs +76 -76
- package/dist/entries/prompt-builder.js +5 -5
- package/dist/{images-ChAOLY5V.d.cts → images-BQ1jUWyZ.d.cts} +32 -3
- package/dist/{images-ChAOLY5V.d.ts → images-BQ1jUWyZ.d.ts} +32 -3
- package/dist/index.cjs +648 -640
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +12 -12
- package/dist/{picker-catalogs-DzLCu6qQ.d.cts → picker-catalogs-BuMGOVWC.d.cts} +1 -1
- package/dist/{picker-catalogs-SDSWrufc.d.ts → picker-catalogs-CVQopXwp.d.ts} +1 -1
- package/package.json +2 -2
- package/src/__tests__/doctrine-roster-completeness.test.ts +3 -0
- package/src/__tests__/factory-preset-previews.test.ts +38 -0
- package/src/__tests__/picker-art-images.test.ts +54 -0
- package/src/__tests__/seedance-extend.test.ts +15 -0
- package/src/factory-presets/index.ts +2 -0
- package/src/factory-presets/preview-files.generated.ts +472 -0
- package/src/factory-presets/previews.ts +17 -2
- package/src/picker-art/images.ts +39 -2
- package/src/picker-catalogs.ts +4 -2
- package/src/prompt-wizard-categories.ts +3 -0
- package/dist/chunk-56HWABF5.cjs.map +0 -1
- package/dist/chunk-5XPELUES.js.map +0 -1
- package/dist/chunk-E5EKWWOO.cjs.map +0 -1
- package/dist/chunk-FFPFBNXH.cjs.map +0 -1
- package/dist/chunk-H322GC7M.js.map +0 -1
- package/dist/chunk-IVRSNUYX.js.map +0 -1
- package/dist/chunk-XUMEDRML.cjs.map +0 -1
- package/dist/chunk-YDG3KMCN.js.map +0 -1
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkP5HAPDV3_cjs = require('./chunk-P5HAPDV3.cjs');
|
|
4
|
+
var chunkXMRDZRGV_cjs = require('./chunk-XMRDZRGV.cjs');
|
|
5
5
|
|
|
6
6
|
// src/read-node-direction.ts
|
|
7
7
|
function readDirectionFields(value) {
|
|
8
8
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
9
9
|
const src = value;
|
|
10
10
|
const out = {};
|
|
11
|
-
for (const spec of
|
|
11
|
+
for (const spec of chunkXMRDZRGV_cjs.DIRECTION_FIELDS) {
|
|
12
12
|
const v = src[spec.key];
|
|
13
13
|
if (typeof v === "string") {
|
|
14
|
-
if (v.length > 0 && v.length <=
|
|
14
|
+
if (v.length > 0 && v.length <= chunkXMRDZRGV_cjs.DIRECTION_ID_MAX_CHARS) out[spec.key] = v;
|
|
15
15
|
} else if (Array.isArray(v)) {
|
|
16
16
|
const kept = [];
|
|
17
17
|
for (const x of v) {
|
|
18
|
-
if (kept.length >=
|
|
19
|
-
if (typeof x === "string" && x.length > 0 && x.length <=
|
|
18
|
+
if (kept.length >= chunkXMRDZRGV_cjs.DIRECTION_ARRAY_CEILING) break;
|
|
19
|
+
if (typeof x === "string" && x.length > 0 && x.length <= chunkXMRDZRGV_cjs.DIRECTION_ID_MAX_CHARS) {
|
|
20
20
|
kept.push(x);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -29,19 +29,19 @@ function readSubjectFields(value) {
|
|
|
29
29
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
30
30
|
const src = value;
|
|
31
31
|
const out = {};
|
|
32
|
-
for (const key of
|
|
32
|
+
for (const key of chunkP5HAPDV3_cjs.getRegisteredSubjectKeys()) {
|
|
33
33
|
const v = src[key];
|
|
34
|
-
if (key ===
|
|
34
|
+
if (key === chunkP5HAPDV3_cjs.SUBJECT_CUSTOM_AGE_KEY) {
|
|
35
35
|
if (typeof v === "number" && Number.isFinite(v)) out[key] = v;
|
|
36
36
|
continue;
|
|
37
37
|
}
|
|
38
38
|
if (typeof v === "string") {
|
|
39
|
-
if (v.length > 0 && v.length <=
|
|
39
|
+
if (v.length > 0 && v.length <= chunkP5HAPDV3_cjs.SUBJECT_ID_MAX_CHARS) out[key] = v;
|
|
40
40
|
} else if (Array.isArray(v)) {
|
|
41
41
|
const kept = [];
|
|
42
42
|
for (const x of v) {
|
|
43
|
-
if (kept.length >=
|
|
44
|
-
if (typeof x === "string" && x.length > 0 && x.length <=
|
|
43
|
+
if (kept.length >= chunkP5HAPDV3_cjs.SUBJECT_ARRAY_CEILING) break;
|
|
44
|
+
if (typeof x === "string" && x.length > 0 && x.length <= chunkP5HAPDV3_cjs.SUBJECT_ID_MAX_CHARS) {
|
|
45
45
|
kept.push(x);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -118,5 +118,5 @@ function readStructuredFields(value) {
|
|
|
118
118
|
exports.readDirectionFields = readDirectionFields;
|
|
119
119
|
exports.readStructuredFields = readStructuredFields;
|
|
120
120
|
exports.readSubjectFields = readSubjectFields;
|
|
121
|
-
//# sourceMappingURL=chunk-
|
|
122
|
-
//# sourceMappingURL=chunk-
|
|
121
|
+
//# sourceMappingURL=chunk-2MTFPGQC.cjs.map
|
|
122
|
+
//# sourceMappingURL=chunk-2MTFPGQC.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/read-node-direction.ts"],"names":["DIRECTION_FIELDS","DIRECTION_ID_MAX_CHARS","DIRECTION_ARRAY_CEILING","getRegisteredSubjectKeys","SUBJECT_CUSTOM_AGE_KEY","SUBJECT_ID_MAX_CHARS","SUBJECT_ARRAY_CEILING"],"mappings":"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","file":"chunk-P4BXE4OA.cjs","sourcesContent":["/**\n * Narrow readers turning UNTRUSTED persisted node data (`workflows.nodes`\n * JSONB — import, MCP write, node preset, a Studio-emitted graph) into the\n * typed `subject` / `direction` / `structured` levers `assembleImageInput`\n * accepts.\n * `buildPayload` has no zod and workflow writes are\n * `z.record(z.string(), z.unknown())`, so this blob may have been written years\n * ago by any client.\n *\n * Used by ALL THREE image-assembly sites so what the canvas accepts cannot\n * drift between them: the frontend single-node executor (`execute-node.ts`),\n * the orchestrator (`payload-builder.ts`), and the config-panel final-prompt\n * preview (`build-image-assemble-input.ts`).\n *\n * `readDirectionFields` is DERIVED FROM `DIRECTION_FIELDS`, never a hand list:\n * a dimension added to the registry is honored here by construction, so the\n * reader can never silently drop a key the wire schema and the renderer both\n * know about. Anything unrecognised is DROPPED, never thrown on — a malformed\n * blob must not fail a canvas run, and an unknown catalog ID already degrades\n * to `\"\"` inside each `get*PromptHint`, so this validates SHAPE only.\n *\n * BOUNDS MATCH THE WIRE SCHEMA where both exist, by SHARED CONSTANT:\n * `DIRECTION_ID_MAX_CHARS` and `DIRECTION_ARRAY_CEILING` are the same two\n * literals the `generate-image` route's `directionSchema` enforces, imported\n * from the registry rather than re-typed here — a body the route accepts and a\n * node the canvas re-runs must not disagree about which strings are ids.\n *\n * DELIBERATELY STRICTER THAN THE WIRE SCHEMA on `structured` values: the\n * route's `structuredPromptFieldsSchema` declares every field as a bare\n * `z.string().optional()` (unbounded), while `MAX_STRUCTURED_VALUE_CHARS` below\n * bounds them at 200. Do not \"fix\" that asymmetry by loosening HERE — this\n * reads a blob any client may have written years ago, and the values land\n * verbatim in `jobs.input_data.prompt`. Tightening the ROUTE instead would be a\n * new 400 on currently-accepted input, so a >200-char structured value stored\n * on a node is dropped on a canvas run while `POST /v1/generate-image` still\n * renders it. That is the one known divergence; it is bounded to a field the\n * canvas UI never writes that long.\n *\n * RETURNS `undefined`, NEVER `{}`: an empty object would still be a *defined*\n * `direction`, and the call sites' `...(x !== undefined ? { x } : {})` spread\n * would then hand `assembleImageInput` a defined-but-empty lever. Returning\n * `undefined` keeps that spread honest and the exact no-op branch taken.\n */\nimport {\n DIRECTION_ARRAY_CEILING,\n DIRECTION_FIELDS,\n DIRECTION_ID_MAX_CHARS,\n type DirectionFields,\n} from \"./direction-registry.js\"\nimport {\n SUBJECT_ARRAY_CEILING,\n SUBJECT_CUSTOM_AGE_KEY,\n SUBJECT_ID_MAX_CHARS,\n getRegisteredSubjectKeys,\n type SubjectFields,\n} from \"./subject-registry.js\"\nimport type { StructuredPromptFields } from \"./prompt-builder-structured-fields.js\"\n\n/**\n * Read a node's stored cinematic-direction ids. Accepts a single id OR an array\n * on every key (multi-pick dimensions carry arrays; a single-pick key may\n * legitimately carry one).\n *\n * The SEMANTIC per-dimension cap stays the renderer's slice (`maxPicks`) — this\n * reader does not know a row's pick budget and must not guess it. But it DOES\n * bound cardinality at `DIRECTION_ARRAY_CEILING`, the same ceiling the wire\n * schema enforces: the value is untrusted persisted JSONB (a node blob is\n * validated only as `z.record(z.string(), z.unknown())` on write), and handing\n * an unbounded array to `renderDirectionHints` would put an `includes`-dedupe\n * scan in front of that slice. Keeping the FIRST `DIRECTION_ARRAY_CEILING`\n * survivors is what the wire door already does to the same input.\n *\n * Junk is filtered BEFORE the cap, so valid ids sitting behind malformed\n * entries survive rather than being crowded out by them.\n */\nexport function readDirectionFields(value: unknown): DirectionFields | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined\n const src = value as Record<string, unknown>\n const out: Record<string, string | string[]> = {}\n for (const spec of DIRECTION_FIELDS) {\n const v = src[spec.key]\n if (typeof v === \"string\") {\n if (v.length > 0 && v.length <= DIRECTION_ID_MAX_CHARS) out[spec.key] = v\n } else if (Array.isArray(v)) {\n const kept: string[] = []\n for (const x of v) {\n if (kept.length >= DIRECTION_ARRAY_CEILING) break\n if (typeof x === \"string\" && x.length > 0 && x.length <= DIRECTION_ID_MAX_CHARS) {\n kept.push(x)\n }\n }\n if (kept.length > 0) out[spec.key] = kept\n }\n }\n return Object.keys(out).length > 0 ? (out as DirectionFields) : undefined\n}\n\n// ── subject ──────────────────────────────────────────────────────────────────\n\n/**\n * Read a node's stored SUBJECT ids — the flat Person / Styling / prop bag the\n * `subject` channel carries. Same three contracts as `readDirectionFields`:\n * drop-never-throw, `undefined` never `{}`, and bounds shared with the wire\n * door by CONSTANT (`SUBJECT_ID_MAX_CHARS` / `SUBJECT_ARRAY_CEILING`, which are\n * defined AS the direction constants) so a body the route accepts and the same\n * node re-run from the canvas cannot disagree about which strings are ids.\n *\n * DERIVED from `getRegisteredSubjectKeys()`, never a hand-authored field list —\n * that is the whole lesson of `readStructuredFields` below, whose hand table is\n * only viable because `StructuredPromptFields` is a small hand-authored type.\n * The subject vocabulary is ~54 catalog-derived fields PLUS deployment-registered\n * pack dimensions unknown at compile time, so it is read from the registry at\n * call time. Iterating the KEY SET (never `Object.keys(value)`) is also what\n * keeps an adversarial blob's key count off the hot path.\n *\n * The SEMANTIC per-dimension cap stays the renderer's job\n * (`normalizeSubjectFields`), exactly as `maxPicks` does for direction: this\n * reader bounds cardinality only. `customAge` is the one number on the wire and\n * is passed through finite-only — the renderer clamps it.\n */\nexport function readSubjectFields(value: unknown): SubjectFields | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined\n const src = value as Record<string, unknown>\n const out: Record<string, string | string[] | number> = {}\n for (const key of getRegisteredSubjectKeys()) {\n const v = src[key]\n if (key === SUBJECT_CUSTOM_AGE_KEY) {\n if (typeof v === \"number\" && Number.isFinite(v)) out[key] = v\n continue\n }\n if (typeof v === \"string\") {\n if (v.length > 0 && v.length <= SUBJECT_ID_MAX_CHARS) out[key] = v\n } else if (Array.isArray(v)) {\n // Junk is filtered BEFORE the cap, so valid ids sitting behind malformed\n // entries survive rather than being crowded out by them.\n const kept: string[] = []\n for (const x of v) {\n if (kept.length >= SUBJECT_ARRAY_CEILING) break\n if (typeof x === \"string\" && x.length > 0 && x.length <= SUBJECT_ID_MAX_CHARS) {\n kept.push(x)\n }\n }\n if (kept.length > 0) out[key] = kept\n }\n }\n return Object.keys(out).length > 0 ? (out as SubjectFields) : undefined\n}\n\n// ── structured ───────────────────────────────────────────────────────────────\n\ntype FieldKind = \"string\" | \"number\" | \"gender\"\nconst GENDERS = [\"man\", \"woman\", \"child\", \"non-binary\"] as const\nconst MAX_STRUCTURED_VALUE_CHARS = 200\n\ntype Group = Exclude<keyof StructuredPromptFields, \"mood\">\ntype GroupFields<K extends Group> = Record<keyof NonNullable<StructuredPromptFields[K]>, FieldKind>\n\n/**\n * A FIELD-BY-FIELD table (not a registry walk) on purpose:\n * `StructuredPromptFields` is a small HAND-AUTHORED type, not catalog-derived,\n * and the table is what blocks `person: { age: \"drop table\" }` from rendering\n * verbatim into `jobs.input_data.prompt` — `renderStructuredFields` never\n * throws on junk, but it does render it. Totality is enforced by the\n * `GroupFields<K>` / `{ [K in Group]: … }` mapped types: a new field or group\n * on the published type fails to typecheck here.\n */\nconst PERSON_FIELDS: GroupFields<\"person\"> = {\n age: \"number\",\n gender: \"gender\",\n hair: \"string\",\n eyes: \"string\",\n expression: \"string\",\n profession: \"string\",\n warriorType: \"string\",\n}\nconst STYLING_FIELDS: GroupFields<\"styling\"> = {\n mood: \"string\",\n lighting: \"string\",\n aesthetic: \"string\",\n colorLook: \"string\",\n}\nconst SETTING_FIELDS: GroupFields<\"setting\"> = {\n era: \"string\",\n atmosphere: \"string\",\n backdrop: \"string\",\n}\nconst CAMERA_FIELDS: GroupFields<\"camera\"> = {\n framing: \"string\",\n motion: \"string\",\n format: \"string\",\n}\nconst LENS_FIELDS: GroupFields<\"lens\"> = { focalLength: \"string\", aperture: \"string\" }\n\nconst STRUCTURED_GROUPS: { [K in Group]: GroupFields<K> } = {\n person: PERSON_FIELDS,\n styling: STYLING_FIELDS,\n setting: SETTING_FIELDS,\n camera: CAMERA_FIELDS,\n lens: LENS_FIELDS,\n}\n\nfunction readField(v: unknown, kind: FieldKind): string | number | undefined {\n if (kind === \"number\") return typeof v === \"number\" && Number.isFinite(v) ? v : undefined\n if (typeof v !== \"string\" || v.length === 0 || v.length > MAX_STRUCTURED_VALUE_CHARS) {\n return undefined\n }\n if (kind === \"gender\") return (GENDERS as readonly string[]).includes(v) ? v : undefined\n return v\n}\n\n/** Read a node's stored Path-1 structured prompt fields. Same drop-never-throw\n * and `undefined`-never-`{}` contract as `readDirectionFields`. */\nexport function readStructuredFields(value: unknown): StructuredPromptFields | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined\n const src = value as Record<string, unknown>\n const out: Record<string, unknown> = {}\n for (const group of Object.keys(STRUCTURED_GROUPS) as Group[]) {\n const raw = src[group]\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) continue\n const rawRec = raw as Record<string, unknown>\n const kept: Record<string, unknown> = {}\n for (const [field, kind] of Object.entries(\n STRUCTURED_GROUPS[group] as Record<string, FieldKind>,\n )) {\n const v = readField(rawRec[field], kind)\n if (v !== undefined) kept[field] = v\n }\n if (Object.keys(kept).length > 0) out[group] = kept\n }\n const mood = readField(src.mood, \"string\")\n if (mood !== undefined) out.mood = mood\n return Object.keys(out).length > 0 ? (out as StructuredPromptFields) : undefined\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/read-node-direction.ts"],"names":["DIRECTION_FIELDS","DIRECTION_ID_MAX_CHARS","DIRECTION_ARRAY_CEILING","getRegisteredSubjectKeys","SUBJECT_CUSTOM_AGE_KEY","SUBJECT_ID_MAX_CHARS","SUBJECT_ARRAY_CEILING"],"mappings":"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","file":"chunk-2MTFPGQC.cjs","sourcesContent":["/**\n * Narrow readers turning UNTRUSTED persisted node data (`workflows.nodes`\n * JSONB — import, MCP write, node preset, a Studio-emitted graph) into the\n * typed `subject` / `direction` / `structured` levers `assembleImageInput`\n * accepts.\n * `buildPayload` has no zod and workflow writes are\n * `z.record(z.string(), z.unknown())`, so this blob may have been written years\n * ago by any client.\n *\n * Used by ALL THREE image-assembly sites so what the canvas accepts cannot\n * drift between them: the frontend single-node executor (`execute-node.ts`),\n * the orchestrator (`payload-builder.ts`), and the config-panel final-prompt\n * preview (`build-image-assemble-input.ts`).\n *\n * `readDirectionFields` is DERIVED FROM `DIRECTION_FIELDS`, never a hand list:\n * a dimension added to the registry is honored here by construction, so the\n * reader can never silently drop a key the wire schema and the renderer both\n * know about. Anything unrecognised is DROPPED, never thrown on — a malformed\n * blob must not fail a canvas run, and an unknown catalog ID already degrades\n * to `\"\"` inside each `get*PromptHint`, so this validates SHAPE only.\n *\n * BOUNDS MATCH THE WIRE SCHEMA where both exist, by SHARED CONSTANT:\n * `DIRECTION_ID_MAX_CHARS` and `DIRECTION_ARRAY_CEILING` are the same two\n * literals the `generate-image` route's `directionSchema` enforces, imported\n * from the registry rather than re-typed here — a body the route accepts and a\n * node the canvas re-runs must not disagree about which strings are ids.\n *\n * DELIBERATELY STRICTER THAN THE WIRE SCHEMA on `structured` values: the\n * route's `structuredPromptFieldsSchema` declares every field as a bare\n * `z.string().optional()` (unbounded), while `MAX_STRUCTURED_VALUE_CHARS` below\n * bounds them at 200. Do not \"fix\" that asymmetry by loosening HERE — this\n * reads a blob any client may have written years ago, and the values land\n * verbatim in `jobs.input_data.prompt`. Tightening the ROUTE instead would be a\n * new 400 on currently-accepted input, so a >200-char structured value stored\n * on a node is dropped on a canvas run while `POST /v1/generate-image` still\n * renders it. That is the one known divergence; it is bounded to a field the\n * canvas UI never writes that long.\n *\n * RETURNS `undefined`, NEVER `{}`: an empty object would still be a *defined*\n * `direction`, and the call sites' `...(x !== undefined ? { x } : {})` spread\n * would then hand `assembleImageInput` a defined-but-empty lever. Returning\n * `undefined` keeps that spread honest and the exact no-op branch taken.\n */\nimport {\n DIRECTION_ARRAY_CEILING,\n DIRECTION_FIELDS,\n DIRECTION_ID_MAX_CHARS,\n type DirectionFields,\n} from \"./direction-registry.js\"\nimport {\n SUBJECT_ARRAY_CEILING,\n SUBJECT_CUSTOM_AGE_KEY,\n SUBJECT_ID_MAX_CHARS,\n getRegisteredSubjectKeys,\n type SubjectFields,\n} from \"./subject-registry.js\"\nimport type { StructuredPromptFields } from \"./prompt-builder-structured-fields.js\"\n\n/**\n * Read a node's stored cinematic-direction ids. Accepts a single id OR an array\n * on every key (multi-pick dimensions carry arrays; a single-pick key may\n * legitimately carry one).\n *\n * The SEMANTIC per-dimension cap stays the renderer's slice (`maxPicks`) — this\n * reader does not know a row's pick budget and must not guess it. But it DOES\n * bound cardinality at `DIRECTION_ARRAY_CEILING`, the same ceiling the wire\n * schema enforces: the value is untrusted persisted JSONB (a node blob is\n * validated only as `z.record(z.string(), z.unknown())` on write), and handing\n * an unbounded array to `renderDirectionHints` would put an `includes`-dedupe\n * scan in front of that slice. Keeping the FIRST `DIRECTION_ARRAY_CEILING`\n * survivors is what the wire door already does to the same input.\n *\n * Junk is filtered BEFORE the cap, so valid ids sitting behind malformed\n * entries survive rather than being crowded out by them.\n */\nexport function readDirectionFields(value: unknown): DirectionFields | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined\n const src = value as Record<string, unknown>\n const out: Record<string, string | string[]> = {}\n for (const spec of DIRECTION_FIELDS) {\n const v = src[spec.key]\n if (typeof v === \"string\") {\n if (v.length > 0 && v.length <= DIRECTION_ID_MAX_CHARS) out[spec.key] = v\n } else if (Array.isArray(v)) {\n const kept: string[] = []\n for (const x of v) {\n if (kept.length >= DIRECTION_ARRAY_CEILING) break\n if (typeof x === \"string\" && x.length > 0 && x.length <= DIRECTION_ID_MAX_CHARS) {\n kept.push(x)\n }\n }\n if (kept.length > 0) out[spec.key] = kept\n }\n }\n return Object.keys(out).length > 0 ? (out as DirectionFields) : undefined\n}\n\n// ── subject ──────────────────────────────────────────────────────────────────\n\n/**\n * Read a node's stored SUBJECT ids — the flat Person / Styling / prop bag the\n * `subject` channel carries. Same three contracts as `readDirectionFields`:\n * drop-never-throw, `undefined` never `{}`, and bounds shared with the wire\n * door by CONSTANT (`SUBJECT_ID_MAX_CHARS` / `SUBJECT_ARRAY_CEILING`, which are\n * defined AS the direction constants) so a body the route accepts and the same\n * node re-run from the canvas cannot disagree about which strings are ids.\n *\n * DERIVED from `getRegisteredSubjectKeys()`, never a hand-authored field list —\n * that is the whole lesson of `readStructuredFields` below, whose hand table is\n * only viable because `StructuredPromptFields` is a small hand-authored type.\n * The subject vocabulary is ~54 catalog-derived fields PLUS deployment-registered\n * pack dimensions unknown at compile time, so it is read from the registry at\n * call time. Iterating the KEY SET (never `Object.keys(value)`) is also what\n * keeps an adversarial blob's key count off the hot path.\n *\n * The SEMANTIC per-dimension cap stays the renderer's job\n * (`normalizeSubjectFields`), exactly as `maxPicks` does for direction: this\n * reader bounds cardinality only. `customAge` is the one number on the wire and\n * is passed through finite-only — the renderer clamps it.\n */\nexport function readSubjectFields(value: unknown): SubjectFields | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined\n const src = value as Record<string, unknown>\n const out: Record<string, string | string[] | number> = {}\n for (const key of getRegisteredSubjectKeys()) {\n const v = src[key]\n if (key === SUBJECT_CUSTOM_AGE_KEY) {\n if (typeof v === \"number\" && Number.isFinite(v)) out[key] = v\n continue\n }\n if (typeof v === \"string\") {\n if (v.length > 0 && v.length <= SUBJECT_ID_MAX_CHARS) out[key] = v\n } else if (Array.isArray(v)) {\n // Junk is filtered BEFORE the cap, so valid ids sitting behind malformed\n // entries survive rather than being crowded out by them.\n const kept: string[] = []\n for (const x of v) {\n if (kept.length >= SUBJECT_ARRAY_CEILING) break\n if (typeof x === \"string\" && x.length > 0 && x.length <= SUBJECT_ID_MAX_CHARS) {\n kept.push(x)\n }\n }\n if (kept.length > 0) out[key] = kept\n }\n }\n return Object.keys(out).length > 0 ? (out as SubjectFields) : undefined\n}\n\n// ── structured ───────────────────────────────────────────────────────────────\n\ntype FieldKind = \"string\" | \"number\" | \"gender\"\nconst GENDERS = [\"man\", \"woman\", \"child\", \"non-binary\"] as const\nconst MAX_STRUCTURED_VALUE_CHARS = 200\n\ntype Group = Exclude<keyof StructuredPromptFields, \"mood\">\ntype GroupFields<K extends Group> = Record<keyof NonNullable<StructuredPromptFields[K]>, FieldKind>\n\n/**\n * A FIELD-BY-FIELD table (not a registry walk) on purpose:\n * `StructuredPromptFields` is a small HAND-AUTHORED type, not catalog-derived,\n * and the table is what blocks `person: { age: \"drop table\" }` from rendering\n * verbatim into `jobs.input_data.prompt` — `renderStructuredFields` never\n * throws on junk, but it does render it. Totality is enforced by the\n * `GroupFields<K>` / `{ [K in Group]: … }` mapped types: a new field or group\n * on the published type fails to typecheck here.\n */\nconst PERSON_FIELDS: GroupFields<\"person\"> = {\n age: \"number\",\n gender: \"gender\",\n hair: \"string\",\n eyes: \"string\",\n expression: \"string\",\n profession: \"string\",\n warriorType: \"string\",\n}\nconst STYLING_FIELDS: GroupFields<\"styling\"> = {\n mood: \"string\",\n lighting: \"string\",\n aesthetic: \"string\",\n colorLook: \"string\",\n}\nconst SETTING_FIELDS: GroupFields<\"setting\"> = {\n era: \"string\",\n atmosphere: \"string\",\n backdrop: \"string\",\n}\nconst CAMERA_FIELDS: GroupFields<\"camera\"> = {\n framing: \"string\",\n motion: \"string\",\n format: \"string\",\n}\nconst LENS_FIELDS: GroupFields<\"lens\"> = { focalLength: \"string\", aperture: \"string\" }\n\nconst STRUCTURED_GROUPS: { [K in Group]: GroupFields<K> } = {\n person: PERSON_FIELDS,\n styling: STYLING_FIELDS,\n setting: SETTING_FIELDS,\n camera: CAMERA_FIELDS,\n lens: LENS_FIELDS,\n}\n\nfunction readField(v: unknown, kind: FieldKind): string | number | undefined {\n if (kind === \"number\") return typeof v === \"number\" && Number.isFinite(v) ? v : undefined\n if (typeof v !== \"string\" || v.length === 0 || v.length > MAX_STRUCTURED_VALUE_CHARS) {\n return undefined\n }\n if (kind === \"gender\") return (GENDERS as readonly string[]).includes(v) ? v : undefined\n return v\n}\n\n/** Read a node's stored Path-1 structured prompt fields. Same drop-never-throw\n * and `undefined`-never-`{}` contract as `readDirectionFields`. */\nexport function readStructuredFields(value: unknown): StructuredPromptFields | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined\n const src = value as Record<string, unknown>\n const out: Record<string, unknown> = {}\n for (const group of Object.keys(STRUCTURED_GROUPS) as Group[]) {\n const raw = src[group]\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) continue\n const rawRec = raw as Record<string, unknown>\n const kept: Record<string, unknown> = {}\n for (const [field, kind] of Object.entries(\n STRUCTURED_GROUPS[group] as Record<string, FieldKind>,\n )) {\n const v = readField(rawRec[field], kind)\n if (v !== undefined) kept[field] = v\n }\n if (Object.keys(kept).length > 0) out[group] = kept\n }\n const mood = readField(src.mood, \"string\")\n if (mood !== undefined) out.mood = mood\n return Object.keys(out).length > 0 ? (out as StructuredPromptFields) : undefined\n}\n"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkP5HAPDV3_cjs = require('./chunk-P5HAPDV3.cjs');
|
|
4
4
|
var chunkXUZXBY75_cjs = require('./chunk-XUZXBY75.cjs');
|
|
5
5
|
var chunk2NJTFCKQ_cjs = require('./chunk-2NJTFCKQ.cjs');
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var
|
|
6
|
+
var chunkBHBZN2AP_cjs = require('./chunk-BHBZN2AP.cjs');
|
|
7
|
+
var chunkXMRDZRGV_cjs = require('./chunk-XMRDZRGV.cjs');
|
|
8
|
+
var chunkFEHXLXAV_cjs = require('./chunk-FEHXLXAV.cjs');
|
|
9
9
|
var entities = require('@nodaro/shared/entities');
|
|
10
10
|
var models = require('@nodaro/shared/models');
|
|
11
11
|
var video = require('@nodaro/shared/video');
|
|
@@ -147,11 +147,11 @@ function resolveSeatlessAssets(args) {
|
|
|
147
147
|
var REFERENCE_TOKEN_RE = /\{(image|video|audio):(\d+)(?::([a-zA-Z0-9_ -]+))?\}/gi;
|
|
148
148
|
function resolveReferenceTokens(prompt, counts) {
|
|
149
149
|
if (!prompt) return prompt;
|
|
150
|
-
return
|
|
150
|
+
return chunkP5HAPDV3_cjs.tidyReferenceTokenGaps(
|
|
151
151
|
prompt.replace(REFERENCE_TOKEN_RE, (_match, rawKind, nStr, label) => {
|
|
152
152
|
const kind = rawKind.toLowerCase();
|
|
153
153
|
const n = parseInt(nStr, 10);
|
|
154
|
-
if (n < 1 || n > counts[kind]) return
|
|
154
|
+
if (n < 1 || n > counts[kind]) return chunkP5HAPDV3_cjs.unboundReferenceTokenText(label);
|
|
155
155
|
if (label) return REF_BINDING[kind](label, n);
|
|
156
156
|
return `@${kind}_${n}`;
|
|
157
157
|
})
|
|
@@ -210,7 +210,7 @@ function resolveVideoCharacterMentionsHybrid(prompt, tokens, refs, offset) {
|
|
|
210
210
|
const binding = bindingFor(m.url);
|
|
211
211
|
const lock = chunk2NJTFCKQ_cjs.buildIdentityLockLine(chunk2NJTFCKQ_cjs.withForcedIdentityLock(ref, lockOverrideByUrl.get(m.url)), binding);
|
|
212
212
|
if (lock) lockLines.push(lock);
|
|
213
|
-
const overrideLine =
|
|
213
|
+
const overrideLine = chunkP5HAPDV3_cjs.referenceDescriptionLine(binding, ref.descriptionOverride);
|
|
214
214
|
if (overrideLine) elementDirectives.push(overrideLine);
|
|
215
215
|
const inject = ref.elementInjection?.trim();
|
|
216
216
|
if (inject) elementDirectives.push(inject);
|
|
@@ -245,10 +245,10 @@ function resolveVideoReferenceCore(args) {
|
|
|
245
245
|
lookupCharacterBySlug: args.lookupCharacterBySlug
|
|
246
246
|
}) : void 0;
|
|
247
247
|
const describedAndCaptionLines = [
|
|
248
|
-
...
|
|
248
|
+
...chunkP5HAPDV3_cjs.renderDescribedReferenceLines(
|
|
249
249
|
seatless ? [...seatless.identities, ...args.describedReferences ?? []] : args.describedReferences
|
|
250
250
|
),
|
|
251
|
-
...
|
|
251
|
+
...chunkP5HAPDV3_cjs.renderReferenceCaptionLines(args.videoCaptions, args.audioCaptions, {
|
|
252
252
|
video: args.videoRefCount ?? 0,
|
|
253
253
|
audio: args.audioRefCount ?? 0
|
|
254
254
|
})
|
|
@@ -286,7 +286,7 @@ function resolveVideoReferenceCore(args) {
|
|
|
286
286
|
// Described references and rail captions are the ONE thing this branch can
|
|
287
287
|
// still contribute: they need no seat, so a request that carries only them
|
|
288
288
|
// (a story landing before any entity exists) reaches the model here.
|
|
289
|
-
prompt: describedAndCaptionLines.length > 0 ?
|
|
289
|
+
prompt: describedAndCaptionLines.length > 0 ? chunkP5HAPDV3_cjs.appendReferenceLines(resolved2 ?? "", describedAndCaptionLines, args.hybridRoles === true ? "hybrid" : "legacy") : resolved2,
|
|
290
290
|
additionalUrls: [...leadingRefUrls]
|
|
291
291
|
};
|
|
292
292
|
}
|
|
@@ -307,7 +307,7 @@ function resolveVideoReferenceCore(args) {
|
|
|
307
307
|
mentionLockLines = h.lockLines;
|
|
308
308
|
mentionElementDirectives = h.elementDirectives;
|
|
309
309
|
} else {
|
|
310
|
-
resolved = mentionTokens.length > 0 ?
|
|
310
|
+
resolved = mentionTokens.length > 0 ? chunkP5HAPDV3_cjs.resolveCharacterMentions(promptForResolution, mentionTokens, wiredCharRefs) : { prompt: promptForResolution, additionalUrls: [], mentionedCharacterSlugs: /* @__PURE__ */ new Set() };
|
|
311
311
|
}
|
|
312
312
|
const fallbackUrls = [];
|
|
313
313
|
const fallbackDirectiveLines = [];
|
|
@@ -344,7 +344,7 @@ function resolveVideoReferenceCore(args) {
|
|
|
344
344
|
canonicalPhrases.push(entities.roleToPhrase(entities.resolveDefaultRole(r.defaultRole, r.defaultUsageMode, r.source), binding));
|
|
345
345
|
const lock = chunk2NJTFCKQ_cjs.buildIdentityLockLine(r, binding);
|
|
346
346
|
if (lock) canonicalLockLines.push(lock);
|
|
347
|
-
const overrideLine =
|
|
347
|
+
const overrideLine = chunkP5HAPDV3_cjs.referenceDescriptionLine(binding, r.descriptionOverride);
|
|
348
348
|
if (overrideLine) canonicalElementDirectives.push(overrideLine);
|
|
349
349
|
const inject = r.elementInjection?.trim();
|
|
350
350
|
if (inject) canonicalElementDirectives.push(inject);
|
|
@@ -476,7 +476,7 @@ function resolveVideoReferenceCore(args) {
|
|
|
476
476
|
const lockBlock = lockLines.length > 0 ? `${lockLines.join("\n")}
|
|
477
477
|
|
|
478
478
|
` : "";
|
|
479
|
-
finalPrompt = `${lockBlock}${
|
|
479
|
+
finalPrompt = `${lockBlock}${chunkP5HAPDV3_cjs.insertBeforeStyleSection(finalPrompt, trailingLines)}`;
|
|
480
480
|
} else {
|
|
481
481
|
const allFallbackLines = [...fallbackDirectiveLines, ...extraDirectiveLines];
|
|
482
482
|
if (allFallbackLines.length > 0) {
|
|
@@ -526,7 +526,7 @@ ${finalPrompt}` : block;
|
|
|
526
526
|
merged.push(u);
|
|
527
527
|
}
|
|
528
528
|
}
|
|
529
|
-
finalPrompt =
|
|
529
|
+
finalPrompt = chunkP5HAPDV3_cjs.appendReferenceLines(
|
|
530
530
|
finalPrompt,
|
|
531
531
|
describedAndCaptionLines,
|
|
532
532
|
hybrid ? "hybrid" : "legacy"
|
|
@@ -554,7 +554,7 @@ ${finalPrompt}` : block;
|
|
|
554
554
|
});
|
|
555
555
|
}
|
|
556
556
|
}
|
|
557
|
-
const reordered =
|
|
557
|
+
const reordered = chunkP5HAPDV3_cjs.applyReferenceOrderToVideo(assetUrls, finalPrompt, refsForOrdering, referenceOrder, void 0, offset);
|
|
558
558
|
return {
|
|
559
559
|
prompt: resolveReferenceTokens(reordered.prompt, tokenCounts(merged.length)),
|
|
560
560
|
additionalUrls: [...leadingRefUrls, ...reordered.urls]
|
|
@@ -608,7 +608,7 @@ function composeSoundHintFromConnections(consumer, consumerType, ctx) {
|
|
|
608
608
|
continue;
|
|
609
609
|
}
|
|
610
610
|
}
|
|
611
|
-
const hint =
|
|
611
|
+
const hint = chunkBHBZN2AP_cjs.getParameterPromptHint(src);
|
|
612
612
|
if (hint) acceptedHints.push(hint);
|
|
613
613
|
if ((consumerType === "suno-generate" || consumerType === "generate-music") && t === "voice-character" && src.data) {
|
|
614
614
|
const gender = src.data.gender;
|
|
@@ -622,14 +622,14 @@ function composeSoundHintFromConnections(consumer, consumerType, ctx) {
|
|
|
622
622
|
const sub = typeof data.subgenre === "string" ? data.subgenre : void 0;
|
|
623
623
|
const genreId = typeof data.genre === "string" ? data.genre : void 0;
|
|
624
624
|
const eraId = typeof data.era === "string" ? data.era : void 0;
|
|
625
|
-
const eraHint =
|
|
626
|
-
const genre =
|
|
625
|
+
const eraHint = chunkFEHXLXAV_cjs.getMusicEra(eraId)?.promptHint;
|
|
626
|
+
const genre = chunkFEHXLXAV_cjs.getMusicGenre(genreId);
|
|
627
627
|
const subHint = genre?.subgenres.find((s) => s.id === sub)?.promptHint ?? genre?.promptHint;
|
|
628
628
|
const composed = [eraHint, subHint].filter(Boolean).join(" ");
|
|
629
629
|
if (composed && !fields.genre) Object.assign(fields, { genre: composed });
|
|
630
630
|
}
|
|
631
631
|
if (t === "music-mood" && data) {
|
|
632
|
-
const composed =
|
|
632
|
+
const composed = chunkFEHXLXAV_cjs.buildMusicMoodHints({
|
|
633
633
|
energy: typeof data.energy === "string" ? data.energy : void 0,
|
|
634
634
|
emotion: data.emotion,
|
|
635
635
|
vibe: data.vibe
|
|
@@ -716,23 +716,23 @@ function assembleSunoInput(input) {
|
|
|
716
716
|
function renderImageHintPieces(subject, direction, structured, directionRefs) {
|
|
717
717
|
return {
|
|
718
718
|
hintClauses: [
|
|
719
|
-
...
|
|
720
|
-
|
|
719
|
+
...chunkP5HAPDV3_cjs.asBodyClauses(
|
|
720
|
+
chunkP5HAPDV3_cjs.renderSubjectHints(subject, {
|
|
721
721
|
surface: "image",
|
|
722
|
-
mode:
|
|
722
|
+
mode: chunkP5HAPDV3_cjs.SUBJECT_IMAGE_HINT_MODE_DEFAULT
|
|
723
723
|
})
|
|
724
724
|
),
|
|
725
|
-
...
|
|
725
|
+
...chunkP5HAPDV3_cjs.partitionStyleClauses(direction, {
|
|
726
726
|
surface: "image",
|
|
727
|
-
mode:
|
|
727
|
+
mode: chunkXMRDZRGV_cjs.IMAGE_HINT_MODE_DEFAULT,
|
|
728
728
|
...directionRefs !== void 0 ? { refs: directionRefs } : {}
|
|
729
729
|
})
|
|
730
730
|
].filter((c) => c.text.length > 0),
|
|
731
|
-
structuredFragment: structured ?
|
|
731
|
+
structuredFragment: structured ? chunkP5HAPDV3_cjs.renderStructuredFields(structured) : ""
|
|
732
732
|
};
|
|
733
733
|
}
|
|
734
734
|
function composePromptText(userPrompt, pieces, keptHintClauses) {
|
|
735
|
-
return
|
|
735
|
+
return chunkP5HAPDV3_cjs.composeSectionedPrompt(
|
|
736
736
|
userPrompt,
|
|
737
737
|
pieces.hintClauses.slice(0, keptHintClauses),
|
|
738
738
|
pieces.structuredFragment
|
|
@@ -779,12 +779,12 @@ function styleConnectedReference(s, index) {
|
|
|
779
779
|
url: s.url,
|
|
780
780
|
isExtraRef: true,
|
|
781
781
|
defaultRole: "style",
|
|
782
|
-
description:
|
|
782
|
+
description: chunkXMRDZRGV_cjs.styleReferenceDescription(index, s.caption)
|
|
783
783
|
};
|
|
784
784
|
}
|
|
785
785
|
function assembleOnce(input) {
|
|
786
786
|
const pieces = renderImageHintPieces(input.subject, input.direction, input.structured, input.directionRefs);
|
|
787
|
-
const assembleWith = (keptHintClauses) =>
|
|
787
|
+
const assembleWith = (keptHintClauses) => chunkP5HAPDV3_cjs.buildImagePromptWithOverflow({
|
|
788
788
|
prompt: composePromptText(input.userPrompt, pieces, keptHintClauses),
|
|
789
789
|
provider: input.provider,
|
|
790
790
|
...input.connectedReferences !== void 0 ? { connectedReferences: input.connectedReferences } : {},
|
|
@@ -812,7 +812,7 @@ function assembleOnce(input) {
|
|
|
812
812
|
let kept = pieces.hintClauses.length;
|
|
813
813
|
let fitted = assembleWith(kept);
|
|
814
814
|
if (fitted.overflowChars > 0) {
|
|
815
|
-
const costs =
|
|
815
|
+
const costs = chunkP5HAPDV3_cjs.sectionedClauseCosts(
|
|
816
816
|
input.userPrompt,
|
|
817
817
|
pieces.hintClauses,
|
|
818
818
|
pieces.structuredFragment
|
|
@@ -830,19 +830,19 @@ function assembleOnce(input) {
|
|
|
830
830
|
// src/assemble-video-input.ts
|
|
831
831
|
function composeVideoPromptText(userPrompt, direction, structured, opts) {
|
|
832
832
|
const hintClauses = [
|
|
833
|
-
...
|
|
834
|
-
|
|
833
|
+
...chunkP5HAPDV3_cjs.asBodyClauses(
|
|
834
|
+
chunkP5HAPDV3_cjs.renderSubjectHints(opts?.subject, {
|
|
835
835
|
surface: "video",
|
|
836
|
-
mode: opts?.subjectHintMode ??
|
|
836
|
+
mode: opts?.subjectHintMode ?? chunkP5HAPDV3_cjs.SUBJECT_VIDEO_HINT_MODE_DEFAULT
|
|
837
837
|
})
|
|
838
838
|
),
|
|
839
|
-
...
|
|
839
|
+
...chunkP5HAPDV3_cjs.partitionStyleClauses(direction, {
|
|
840
840
|
surface: "video",
|
|
841
|
-
mode: opts?.hintMode ??
|
|
841
|
+
mode: opts?.hintMode ?? chunkXMRDZRGV_cjs.VIDEO_HINT_MODE_DEFAULT
|
|
842
842
|
})
|
|
843
843
|
].filter((c) => c.text.length > 0);
|
|
844
|
-
const structuredFragment = structured ?
|
|
845
|
-
const composeWith = (kept2) =>
|
|
844
|
+
const structuredFragment = structured ? chunkP5HAPDV3_cjs.renderStructuredFields(structured) : "";
|
|
845
|
+
const composeWith = (kept2) => chunkP5HAPDV3_cjs.composeSectionedPrompt(userPrompt, hintClauses.slice(0, kept2), structuredFragment);
|
|
846
846
|
const cap = opts?.cap;
|
|
847
847
|
if (cap === void 0) return composeWith(hintClauses.length);
|
|
848
848
|
const frame = opts?.frame ?? ((body2) => body2);
|
|
@@ -850,7 +850,7 @@ function composeVideoPromptText(userPrompt, direction, structured, opts) {
|
|
|
850
850
|
let body = composeWith(kept);
|
|
851
851
|
let framedLength = frame(body)?.length ?? 0;
|
|
852
852
|
if (framedLength <= cap) return body;
|
|
853
|
-
const costs =
|
|
853
|
+
const costs = chunkP5HAPDV3_cjs.sectionedClauseCosts(userPrompt, hintClauses, structuredFragment);
|
|
854
854
|
const texts = hintClauses.map((c) => c.text);
|
|
855
855
|
while (framedLength > cap && kept > 0) {
|
|
856
856
|
kept = chunkXUZXBY75_cjs.keepableDirectionHints(texts, kept, framedLength - cap, costs);
|
|
@@ -1074,5 +1074,5 @@ exports.resolveSeedance2Inputs = resolveSeedance2Inputs;
|
|
|
1074
1074
|
exports.resolveVeoI2vInputs = resolveVeoI2vInputs;
|
|
1075
1075
|
exports.resolveVideoReferenceCore = resolveVideoReferenceCore;
|
|
1076
1076
|
exports.truncateForField = truncateForField;
|
|
1077
|
-
//# sourceMappingURL=chunk-
|
|
1078
|
-
//# sourceMappingURL=chunk-
|
|
1077
|
+
//# sourceMappingURL=chunk-32BMZ4Q5.cjs.map
|
|
1078
|
+
//# sourceMappingURL=chunk-32BMZ4Q5.cjs.map
|