From deb1ed1eb3f0909b9bb528ef3856a6e414d436e0 Mon Sep 17 00:00:00 2001 From: chrmc40 Date: Sat, 27 Jun 2026 17:35:59 -0700 Subject: [PATCH] Krea 2 Realism (i2i modal): make the Realism checkbox behave as a preset Ticking Realism on a Krea 2 Turbo i2i edit now drops the author's ClownsharKSampler_Beta recipe defaults (sampler/steps/cfg/denoise) into the dials, while still honoring any value the user has guided away from - the same preset pattern as the 'engine' picker. Unticking restores the engine defaults. Realism still always swaps in the abliterated encoder, wan VAE, and the projector+realism LoRAs regardless of sampler choice. --- js/lib/i2i-background.js | 4 +++- js/lib/svelte/promptchain-viewer.js | 31 +++++++++++++++++++++------ pyproject.toml | 2 +- svelte-src/components/I2IModal.svelte | 20 +++++++++++++---- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/js/lib/i2i-background.js b/js/lib/i2i-background.js index 2346a63..56431f2 100644 --- a/js/lib/i2i-background.js +++ b/js/lib/i2i-background.js @@ -253,7 +253,9 @@ export function buildI2IEngineKrea2(data, options) { } const { ksId } = attachI2ITail(graph, add, { inputRef: data.input_ref, modelRef, clipRef: [clipId, 0], vaeRef: [vaeId, 0], options, - clown: realism, + // Realism defaults to the author's Clown sampler, but the user can pick a + // normal sampler in the modal to override it — then run a plain KSampler. + clown: realism && (!options.sampler || /clownshar/i.test(options.sampler)), steps: numOr(options.steps, raw ? 40 : 8), cfg: numOr(options.cfg, raw ? 3.5 : 1.0), sampler: options.sampler || (raw ? "er_sde" : "euler"), diff --git a/js/lib/svelte/promptchain-viewer.js b/js/lib/svelte/promptchain-viewer.js index fccd124..3c01e4d 100644 --- a/js/lib/svelte/promptchain-viewer.js +++ b/js/lib/svelte/promptchain-viewer.js @@ -4519,7 +4519,7 @@ function I2IModal($$anchor, $$props) { } let recSampler = user_derived(() => { var _a; - return get(engineEntry) ? engineRecipe(get(engineEntry)).sampler : (_a = caps()) == null ? void 0 : _a.recommendedSampler; + return get(realism) ? "ClownsharKSampler_Beta" : get(engineEntry) ? engineRecipe(get(engineEntry)).sampler : (_a = caps()) == null ? void 0 : _a.recommendedSampler; }); let recScheduler = user_derived(() => { var _a; @@ -4527,9 +4527,18 @@ function I2IModal($$anchor, $$props) { }); let recSteps = user_derived(() => engineRecipe(get(engineEntry)).steps); let recCfg = user_derived(() => engineRecipe(get(engineEntry)).cfg); + let samplerOptions = user_derived(() => { + var _a, _b; + return get(realism) ? ["ClownsharKSampler_Beta", ...((_a = caps()) == null ? void 0 : _a.samplerOptions) || []] : ((_b = caps()) == null ? void 0 : _b.samplerOptions) || []; + }); function pickEngine(value) { var _a, _b, _c, _d; set(engineSel, value, true); + set( + realism, + false + // an engine switch resets the Realism preset (re-tick after) + ); const entry = ((_b = (_a = caps()) == null ? void 0 : _a.engineModels) == null ? void 0 : _b.find((m) => m.hash === value)) || null; const r = engineRecipe(entry); if (entry) { @@ -4543,6 +4552,15 @@ function I2IModal($$anchor, $$props) { set(cfg, r.cfg, true); set(denoise, r.denoise, true); } + function setRealism(on) { + set(realism, on, true); + if (on) { + set(sampler, "ClownsharKSampler_Beta"); + set(steps, 8); + set(cfg, 1); + set(denoise, 0.6); + } else pickEngine(get(engineSel)); + } function editorModelInfo() { var _a; if (get(engineEntry)) return { @@ -5007,7 +5025,8 @@ function I2IModal($$anchor, $$props) { var consequent_12 = ($$anchor4) => { var label = root_17$3(); var input = child(label); - bind_checked(input, () => get(realism), ($$value) => set(realism, $$value)); + template_effect(() => set_checked(input, get(realism))); + delegated("change", input, (e) => setRealism(e.currentTarget.checked)); append($$anchor4, label); }; if_block(node_12, ($$render) => { @@ -5084,7 +5103,7 @@ function I2IModal($$anchor, $$props) { var div_33 = child(div_32); var select = sibling(child(div_33), 2); let classes_4; - each(select, 21, () => caps().samplerOptions, index, ($$anchor4, opt) => { + each(select, 21, () => get(samplerOptions), index, ($$anchor4, opt) => { var option = root_23$2(); let styles_1; var text_4 = child(option); @@ -5126,8 +5145,7 @@ function I2IModal($$anchor, $$props) { append($$anchor3, div_32); }; if_block(node_17, ($$render) => { - var _a, _b; - if ((_b = (_a = caps()) == null ? void 0 : _a.samplerOptions) == null ? void 0 : _b.length) $$render(consequent_16); + if (get(samplerOptions).length) $$render(consequent_16); }); } var div_35 = sibling(node_17, 2); @@ -5269,7 +5287,8 @@ delegate([ "pointerdown", "pointermove", "pointerup", - "contextmenu" + "contextmenu", + "change" ]); var root_4$6 = from_html(`
`); var root_3$6 = from_html(`
`); diff --git a/pyproject.toml b/pyproject.toml index ec0c777..013ec33 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ [project] name = "comfyui-promptchain" -version = "0.1.7" +version = "0.1.8" description = "Prompt-authoring and image-iteration suite for ComfyUI: structured prompts, 3D posing, model awareness, regional control, and layered editing." license = { file = "LICENSE" } requires-python = ">=3.10" diff --git a/svelte-src/components/I2IModal.svelte b/svelte-src/components/I2IModal.svelte index 4a2bcca..3b296dc 100644 --- a/svelte-src/components/I2IModal.svelte +++ b/svelte-src/components/I2IModal.svelte @@ -100,13 +100,17 @@ const r = entry.i2i || {}; return { steps: r.steps ?? 0, cfg: r.cfg ?? 0, denoise: r.denoise ?? caps?.defaultDenoise ?? 0.55, sampler: r.sampler || "", scheduler: r.scheduler || "" }; } - let recSampler = $derived(engineEntry ? engineRecipe(engineEntry).sampler : caps?.recommendedSampler); + let recSampler = $derived(realism ? "ClownsharKSampler_Beta" : (engineEntry ? engineRecipe(engineEntry).sampler : caps?.recommendedSampler)); let recScheduler = $derived(engineEntry ? engineRecipe(engineEntry).scheduler : caps?.recommendedScheduler); let recSteps = $derived(engineRecipe(engineEntry).steps); let recCfg = $derived(engineRecipe(engineEntry).cfg); + // Realism adds the author's ClownsharKSampler as a sampler option (its default); + // pick any normal sampler to override it ("guide it away"). + let samplerOptions = $derived(realism ? ["ClownsharKSampler_Beta", ...(caps?.samplerOptions || [])] : (caps?.samplerOptions || [])); function pickEngine(value) { engineSel = value; + realism = false; // an engine switch resets the Realism preset (re-tick after) const entry = caps?.engineModels?.find((m) => m.hash === value) || null; const r = engineRecipe(entry); if (entry) { sampler = r.sampler; scheduler = r.scheduler; } @@ -114,6 +118,14 @@ steps = r.steps; cfg = r.cfg; denoise = r.denoise; } + // Realism is a preset — exactly like picking an engine: ticking it drops the + // recipe into the dials (adjust after); unticking restores the engine's recipe. + function setRealism(on) { + realism = on; + if (on) { sampler = "ClownsharKSampler_Beta"; steps = 8; cfg = 1; denoise = 0.6; } + else pickEngine(engineSel); + } + // Model identity for the prompt editor's templates/autocomplete: the picked // engine model, else the image's own source model. function editorModelInfo() { @@ -455,7 +467,7 @@ {/if} {#if realismAvailable} {/if} @@ -487,12 +499,12 @@ { denoise = v; }} /> - {#if caps?.samplerOptions?.length} + {#if samplerOptions.length}