From 388ca594285daf124bf3a2201ec2942e86ad8e27 Mon Sep 17 00:00:00 2001 From: digital-garbage <133010426+digital-garbage@users.noreply.github.com> Date: Sat, 17 Oct 2026 00:03:04 +0300 Subject: [PATCH] fix: text-only H3 runs no longer need the preset's blank_like; any pipeline with a resizer slot gets the stand-in Co-Authored-By: Claude Sonnet 5.5 --- app/ui/features/generate/inputs.js | 4 +++- app/ui/features/generate/inputs.test.js | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/ui/features/generate/inputs.js b/app/ui/features/generate/inputs.js index 852825c7..1a40a394 100644 --- a/app/ui/features/generate/inputs.js +++ b/app/ui/features/generate/inputs.js @@ -18,7 +18,9 @@ export async function buildInputs({ project, scene, slots, expand, frames, hooks for (const slot of (slots || []).filter((s) => s.node === "FunPackShotCamera")) put(slot, "project", project.id || ""); // what the node keeps per project (the words focus infusion draws on), also for pipelines saved before it was asked for const source = rolesAt(slots, "assets.source_image")[0]; if (source) put(source.slot, "media_id", project.generation_mode === "t2v" ? "" : scene.source_image || ""); // "from a prompt" starts every shot without a picture - const like = source && source.role.blank_like; + // A project saved before the preset said so still has this shape: a picture-resizing slot is enough to know a stand-in fits. + const resizer = (slots || []).find((s) => s.node === "ImageTransformKJ"), enhancer = (slots || []).find((s) => s.node === "FunPackEnhancePrompt"); + const like = source && (source.role.blank_like || (resizer && { slot: resizer.id, width: "target_width", height: "target_height", ...(enhancer ? { unsend: { slot: enhancer.id, input: "use_image" } } : {}) })); if (like && !raw[source.slot.id].media_id) { // text-only: a plain picture of the size the pipeline asks for stands in const target = (slots || []).find((s) => s.id === like.slot) || { inputs: {} }; const size = (name) => (raw[target.id] || {})[name] ?? (target.inputs || {})[name]; diff --git a/app/ui/features/generate/inputs.test.js b/app/ui/features/generate/inputs.test.js index a6f45f79..0cd4694a 100644 --- a/app/ui/features/generate/inputs.test.js +++ b/app/ui/features/generate/inputs.test.js @@ -102,3 +102,11 @@ test("text-only: a slot that can stand in for the picture is told the size of th assert.deepEqual((await run({ generation_mode: "i2v" }, { source_image: "m1" })).inputs.src, { media_id: "m1" }); assert.deepEqual((await run({ generation_mode: "i2v" }, {})).inputs.src, { media_id: "", blank_width: 1344, blank_height: 768 }); }); + +test("text-only on a pipeline saved before the preset named a stand-in: the resizer slot is enough, no preset change needed", async () => { + const s = [{ id: "src", node: "FunPackLoadMedia", roles: [{ at: "assets.source_image", input: "media_id" }] }, { id: "e", node: "FunPackEnhancePrompt", inputs: { use_image: true } }, + { id: "t", node: "ImageTransformKJ", inputs: { target_width: 1344, target_height: 768 }, roles: [{ at: "project.video", input: "target_width" }] }]; + const { inputs } = await buildInputs({ project: { generation_mode: "t2v", video: { target_width: 640 } }, scene: {}, slots: s, expand: async () => null }); + assert.deepEqual(inputs.src, { media_id: "", blank_width: 640, blank_height: 768 }); + assert.deepEqual(inputs.e, { use_image: false }); +});