From 25452cf44a37b677a8efc070914e2df5aefa27d2 Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Fri, 7 Nov 2025 13:47:38 -0600 Subject: [PATCH 01/13] Adds Segment Sampler and Scheduler params --- .../ComfyUIBackend/ComfyUIBackendExtension.cs | 10 +++++++++- .../ComfyUIBackend/WorkflowGeneratorSteps.cs | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs b/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs index 33b8ff361..5462d99f8 100644 --- a/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs +++ b/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs @@ -607,7 +607,7 @@ public static void AssignValuesFromRaw(JObject rawObjectInfo) } } - public static T2IRegisteredParam CustomWorkflowParam, SamplerParam, SchedulerParam, RefinerSamplerParam, RefinerSchedulerParam, RefinerUpscaleMethod, UseIPAdapterForRevision, IPAdapterWeightType, VideoPreviewType, VideoFrameInterpolationMethod, Text2VideoFrameInterpolationMethod, GligenModel, YoloModelInternal, PreferredDType, UseStyleModel, TeaCacheMode, EasyCacheMode, SetClipDevice; + public static T2IRegisteredParam CustomWorkflowParam, SamplerParam, SchedulerParam, RefinerSamplerParam, RefinerSchedulerParam, SegmentSamplerParam, SegmentSchedulerParam, RefinerUpscaleMethod, UseIPAdapterForRevision, IPAdapterWeightType, VideoPreviewType, VideoFrameInterpolationMethod, Text2VideoFrameInterpolationMethod, GligenModel, YoloModelInternal, PreferredDType, UseStyleModel, TeaCacheMode, EasyCacheMode, SetClipDevice; public static T2IRegisteredParam AITemplateParam, DebugRegionalPrompting, ShiftedLatentAverageInit, UseCfgZeroStar, UseTCFG; @@ -728,6 +728,14 @@ public override void OnInit() "normal", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupRefinerOverrides, OrderPriority: -1.5, GetValues: (_) => Schedulers )); + SegmentSamplerParam = T2IParamTypes.Register(new("Segment Sampler", SamplerParam.Type.Description + "\nThis is an override to only affect the Segment stage.", + "euler", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupSegmentOverrides, OrderPriority: 2.1, + GetValues: (_) => Samplers + )); + SegmentSchedulerParam = T2IParamTypes.Register(new("Segment Scheduler", SchedulerParam.Type.Description + "\nThis is an override to only affect the Segment stage.", + "normal", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupSegmentOverrides, OrderPriority: 2.2, + GetValues: (_) => Schedulers + )); for (int i = 0; i < 3; i++) { ControlNetPreprocessorParams[i] = T2IParamTypes.Register(new($"ControlNet{T2IParamTypes.Controlnets[i].NameSuffix} Preprocessor", "The preprocessor to use on the ControlNet input image.\nIf toggled off, will be automatically selected.\nUse 'None' to disable preprocessing.", diff --git a/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs b/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs index ecdc2e35e..537547b62 100644 --- a/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs +++ b/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs @@ -1501,7 +1501,9 @@ JArray doMaskShrinkApply(WorkflowGenerator g, JArray imgIn) int startStep = (int)Math.Round(steps * (1 - part.Strength2)); long seed = g.UserInput.Get(T2IParamTypes.Seed) + 2 + i; double cfg = g.UserInput.GetNullable(T2IParamTypes.CFGScale, part.ContextID, false) ?? g.UserInput.GetNullable(T2IParamTypes.SegmentCFGScale, part.ContextID) ?? g.UserInput.GetNullable(T2IParamTypes.RefinerCFGScale, part.ContextID) ?? g.UserInput.Get(T2IParamTypes.CFGScale, 7, sectionId: part.ContextID); - string sampler = g.CreateKSampler(model, prompt, negPrompt, [g.MaskShrunkInfo.MaskedLatent, 0], cfg, steps, startStep, 10000, seed, false, true, sectionId: part.ContextID); + string explicitSampler = g.UserInput.Get(ComfyUIBackendExtension.SamplerParam, null, sectionId: part.ContextID, includeBase: false) ?? g.UserInput.Get(ComfyUIBackendExtension.SegmentSamplerParam, null); + string explicitScheduler = g.UserInput.Get(ComfyUIBackendExtension.SchedulerParam, null, sectionId: part.ContextID, includeBase: false) ?? g.UserInput.Get(ComfyUIBackendExtension.SegmentSchedulerParam, null); + string sampler = g.CreateKSampler(model, prompt, negPrompt, [g.MaskShrunkInfo.MaskedLatent, 0], cfg, steps, startStep, 10000, seed, false, true, explicitSampler: explicitSampler, explicitScheduler: explicitScheduler, sectionId: part.ContextID); string decoded = g.CreateVAEDecode(vae, [sampler, 0]); g.FinalImageOut = g.RecompositeCropped(g.MaskShrunkInfo.BoundsNode, [g.MaskShrunkInfo.CroppedMask, 0], g.FinalImageOut, [decoded, 0]); g.MaskShrunkInfo = new(null, null, null, null); From c04a37074e9ab22b91495b4599f46ffb7a3715b2 Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Fri, 7 Nov 2025 13:59:14 -0600 Subject: [PATCH 02/13] Adds VAE option --- .../ComfyUIBackend/ComfyUIBackendExtension.cs | 4 ++-- .../ComfyUIBackend/WorkflowGeneratorSteps.cs | 4 ++++ src/Text2Image/T2IParamTypes.cs | 9 ++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs b/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs index 5462d99f8..62295110d 100644 --- a/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs +++ b/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs @@ -729,11 +729,11 @@ public override void OnInit() GetValues: (_) => Schedulers )); SegmentSamplerParam = T2IParamTypes.Register(new("Segment Sampler", SamplerParam.Type.Description + "\nThis is an override to only affect the Segment stage.", - "euler", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupSegmentOverrides, OrderPriority: 2.1, + "euler", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupSegmentOverrides, OrderPriority: 2.3, GetValues: (_) => Samplers )); SegmentSchedulerParam = T2IParamTypes.Register(new("Segment Scheduler", SchedulerParam.Type.Description + "\nThis is an override to only affect the Segment stage.", - "normal", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupSegmentOverrides, OrderPriority: 2.2, + "normal", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupSegmentOverrides, OrderPriority: 2.4, GetValues: (_) => Schedulers )); for (int i = 0; i < 3; i++) diff --git a/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs b/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs index 537547b62..a2861f0c1 100644 --- a/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs +++ b/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs @@ -1379,6 +1379,10 @@ JArray doMaskShrinkApply(WorkflowGenerator g, JArray imgIn) g.FinalLoadedModel = t2iModel; g.FinalModel = model; } + if (g.UserInput.TryGet(T2IParamTypes.SegmentVAE, out T2IModel segmentVae)) + { + vae = g.CreateVAELoader(segmentVae.ToString(g.ModelFolderFormat), g.HasNode("11") ? null : "11"); + } PromptRegion negativeRegion = new(g.UserInput.Get(T2IParamTypes.NegativePrompt, "")); PromptRegion.Part[] negativeParts = [.. negativeRegion.Parts.Where(p => p.Type == PromptRegion.PartType.Segment)]; for (int i = 0; i < parts.Length; i++) diff --git a/src/Text2Image/T2IParamTypes.cs b/src/Text2Image/T2IParamTypes.cs index 04505a0e7..60c6fc7eb 100644 --- a/src/Text2Image/T2IParamTypes.cs +++ b/src/Text2Image/T2IParamTypes.cs @@ -315,7 +315,7 @@ public static string ApplyStringEdit(string prior, string update) public static T2IRegisteredParam CFGScale, VariationSeedStrength, InitImageCreativity, InitImageResetToNorm, InitImageNoise, RefinerControl, RefinerUpscale, RefinerCFGScale, ReVisionStrength, AltResolutionHeightMult, FreeUBlock1, FreeUBlock2, FreeUSkip1, FreeUSkip2, GlobalRegionFactor, EndStepsEarly, SamplerSigmaMin, SamplerSigmaMax, SamplerRho, VideoAugmentationLevel, VideoCFG, VideoMinCFG, Video2VideoCreativity, VideoSwapPercent, VideoExtendSwapPercent, IP2PCFG2, RegionalObjectCleanupFactor, SigmaShift, SegmentThresholdMax, SegmentCFGScale, FluxGuidanceScale; public static T2IRegisteredParam InitImage, MaskImage, VideoEndFrame; - public static T2IRegisteredParam Model, RefinerModel, VAE, RegionalObjectInpaintingModel, SegmentModel, VideoModel, VideoSwapModel, RefinerVAE, ClipLModel, ClipGModel, ClipVisionModel, T5XXLModel, LLaVAModel, LLaMAModel, QwenModel, VideoExtendModel, VideoExtendSwapModel; + public static T2IRegisteredParam Model, RefinerModel, VAE, RegionalObjectInpaintingModel, SegmentModel, SegmentVAE, VideoModel, VideoSwapModel, RefinerVAE, ClipLModel, ClipGModel, ClipVisionModel, T5XXLModel, LLaVAModel, LLaMAModel, QwenModel, VideoExtendModel, VideoExtendSwapModel; public static T2IRegisteredParam> Loras, LoraWeights, LoraTencWeights, LoraSectionConfinement; public static T2IRegisteredParam> PromptImages; public static T2IRegisteredParam OutputIntermediateImages, DoNotSave, DoNotSaveIntermediates, ControlNetPreviewOnly, RevisionZeroPrompt, RemoveBackground, NoSeedIncrement, NoPreviews, VideoBoomerang, ModelSpecificEnhancements, UseInpaintingEncode, MaskCompositeUnthresholded, SaveSegmentMask, InitImageRecompositeMask, UseReferenceOnly, RefinerDoTiling, AutomaticVAE, ZeroNegative, Text2VideoBoomerang, FluxDisableGuidance, SmartImagePromptResizing, @@ -800,12 +800,15 @@ static List listVaes(Session s) SegmentModel = Register(new("Segment Model", "Optionally specify a distinct model to use for 'segment' values.", "", Toggleable: true, Subtype: "Stable-Diffusion", Group: GroupSegmentOverrides, OrderPriority: 2, IsAdvanced: true )); + SegmentVAE = Register(new("Segment VAE", "Optional VAE replacement for the segment stage.", + "None", IgnoreIf: "None", GetValues: listVaes, IsAdvanced: true, OrderPriority: 2.05, Group: GroupSegmentOverrides, Subtype: "VAE", ChangeWeight: 7, DoNotPreview: true + )); SegmentSteps = Register(new("Segment Steps", "Alternate Steps value for when calculating the segment stage.\nThis replaces the 'Steps' total count before calculating the Segment Creativity.", - "40", Min: 1, Max: 200, ViewMax: 100, Step: 1, Examples: ["20", "40", "60"], OrderPriority: 4, Toggleable: true, IsAdvanced: true, Group: GroupSegmentOverrides, ViewType: ParamViewType.SLIDER + "40", Min: 1, Max: 200, ViewMax: 100, Step: 1, Examples: ["20", "40", "60"], OrderPriority: 2.1, Toggleable: true, IsAdvanced: true, Group: GroupSegmentOverrides, ViewType: ParamViewType.SLIDER )); SegmentCFGScale = Register(new("Segment CFG Scale", "For the segment model independently of the base model, how strongly to scale prompt input.\nHigher CFG scales tend to produce more contrast, and lower CFG scales produce less contrast.\n" + "Too-high values can cause corrupted/burnt images, too-low can cause nonsensical images.\n7 is a good baseline. Normal usages vary between 4 and 9.\nSome model types, such as Turbo, expect CFG around 1.", - "7", Min: 0, Max: 100, ViewMax: 20, Step: 0.5, Examples: ["5", "6", "7", "8", "9"], OrderPriority: 5, ViewType: ParamViewType.SLIDER, Group: GroupSegmentOverrides, ChangeWeight: -3, Toggleable: true, IsAdvanced: true + "7", Min: 0, Max: 100, ViewMax: 20, Step: 0.5, Examples: ["5", "6", "7", "8", "9"], OrderPriority: 2.2, ViewType: ParamViewType.SLIDER, Group: GroupSegmentOverrides, ChangeWeight: -3, Toggleable: true, IsAdvanced: true )); // ================================================ Advanced Sampling ================================================ GroupAdvancedSampling = new("Advanced Sampling", Open: false, OrderPriority: 15, IsAdvanced: true); From eda9684d600c82c533845b19703f0270e1348bad Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Fri, 7 Nov 2025 16:12:48 -0600 Subject: [PATCH 03/13] Removes Segment VAE option; hides Segment Sampler/Scheduler from left sidebar --- .../ComfyUIBackend/ComfyUIBackendExtension.cs | 4 ++-- .../ComfyUIBackend/WorkflowGeneratorSteps.cs | 4 ---- src/Text2Image/T2IParamTypes.cs | 5 +---- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs b/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs index 62295110d..f0d626a0c 100644 --- a/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs +++ b/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs @@ -729,11 +729,11 @@ public override void OnInit() GetValues: (_) => Schedulers )); SegmentSamplerParam = T2IParamTypes.Register(new("Segment Sampler", SamplerParam.Type.Description + "\nThis is an override to only affect the Segment stage.", - "euler", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupSegmentOverrides, OrderPriority: 2.3, + "euler", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupSegmentOverrides, OrderPriority: 2.3, VisibleNormally: false, GetValues: (_) => Samplers )); SegmentSchedulerParam = T2IParamTypes.Register(new("Segment Scheduler", SchedulerParam.Type.Description + "\nThis is an override to only affect the Segment stage.", - "normal", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupSegmentOverrides, OrderPriority: 2.4, + "normal", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupSegmentOverrides, OrderPriority: 2.4, VisibleNormally: false, GetValues: (_) => Schedulers )); for (int i = 0; i < 3; i++) diff --git a/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs b/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs index a2861f0c1..537547b62 100644 --- a/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs +++ b/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs @@ -1379,10 +1379,6 @@ JArray doMaskShrinkApply(WorkflowGenerator g, JArray imgIn) g.FinalLoadedModel = t2iModel; g.FinalModel = model; } - if (g.UserInput.TryGet(T2IParamTypes.SegmentVAE, out T2IModel segmentVae)) - { - vae = g.CreateVAELoader(segmentVae.ToString(g.ModelFolderFormat), g.HasNode("11") ? null : "11"); - } PromptRegion negativeRegion = new(g.UserInput.Get(T2IParamTypes.NegativePrompt, "")); PromptRegion.Part[] negativeParts = [.. negativeRegion.Parts.Where(p => p.Type == PromptRegion.PartType.Segment)]; for (int i = 0; i < parts.Length; i++) diff --git a/src/Text2Image/T2IParamTypes.cs b/src/Text2Image/T2IParamTypes.cs index 60c6fc7eb..a6fc5b664 100644 --- a/src/Text2Image/T2IParamTypes.cs +++ b/src/Text2Image/T2IParamTypes.cs @@ -315,7 +315,7 @@ public static string ApplyStringEdit(string prior, string update) public static T2IRegisteredParam CFGScale, VariationSeedStrength, InitImageCreativity, InitImageResetToNorm, InitImageNoise, RefinerControl, RefinerUpscale, RefinerCFGScale, ReVisionStrength, AltResolutionHeightMult, FreeUBlock1, FreeUBlock2, FreeUSkip1, FreeUSkip2, GlobalRegionFactor, EndStepsEarly, SamplerSigmaMin, SamplerSigmaMax, SamplerRho, VideoAugmentationLevel, VideoCFG, VideoMinCFG, Video2VideoCreativity, VideoSwapPercent, VideoExtendSwapPercent, IP2PCFG2, RegionalObjectCleanupFactor, SigmaShift, SegmentThresholdMax, SegmentCFGScale, FluxGuidanceScale; public static T2IRegisteredParam InitImage, MaskImage, VideoEndFrame; - public static T2IRegisteredParam Model, RefinerModel, VAE, RegionalObjectInpaintingModel, SegmentModel, SegmentVAE, VideoModel, VideoSwapModel, RefinerVAE, ClipLModel, ClipGModel, ClipVisionModel, T5XXLModel, LLaVAModel, LLaMAModel, QwenModel, VideoExtendModel, VideoExtendSwapModel; + public static T2IRegisteredParam Model, RefinerModel, VAE, RegionalObjectInpaintingModel, SegmentModel, VideoModel, VideoSwapModel, RefinerVAE, ClipLModel, ClipGModel, ClipVisionModel, T5XXLModel, LLaVAModel, LLaMAModel, QwenModel, VideoExtendModel, VideoExtendSwapModel; public static T2IRegisteredParam> Loras, LoraWeights, LoraTencWeights, LoraSectionConfinement; public static T2IRegisteredParam> PromptImages; public static T2IRegisteredParam OutputIntermediateImages, DoNotSave, DoNotSaveIntermediates, ControlNetPreviewOnly, RevisionZeroPrompt, RemoveBackground, NoSeedIncrement, NoPreviews, VideoBoomerang, ModelSpecificEnhancements, UseInpaintingEncode, MaskCompositeUnthresholded, SaveSegmentMask, InitImageRecompositeMask, UseReferenceOnly, RefinerDoTiling, AutomaticVAE, ZeroNegative, Text2VideoBoomerang, FluxDisableGuidance, SmartImagePromptResizing, @@ -800,9 +800,6 @@ static List listVaes(Session s) SegmentModel = Register(new("Segment Model", "Optionally specify a distinct model to use for 'segment' values.", "", Toggleable: true, Subtype: "Stable-Diffusion", Group: GroupSegmentOverrides, OrderPriority: 2, IsAdvanced: true )); - SegmentVAE = Register(new("Segment VAE", "Optional VAE replacement for the segment stage.", - "None", IgnoreIf: "None", GetValues: listVaes, IsAdvanced: true, OrderPriority: 2.05, Group: GroupSegmentOverrides, Subtype: "VAE", ChangeWeight: 7, DoNotPreview: true - )); SegmentSteps = Register(new("Segment Steps", "Alternate Steps value for when calculating the segment stage.\nThis replaces the 'Steps' total count before calculating the Segment Creativity.", "40", Min: 1, Max: 200, ViewMax: 100, Step: 1, Examples: ["20", "40", "60"], OrderPriority: 2.1, Toggleable: true, IsAdvanced: true, Group: GroupSegmentOverrides, ViewType: ParamViewType.SLIDER )); From 42b170098e1ce860c49d9048e62dfcf98c1a75cb Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Fri, 7 Nov 2025 16:47:52 -0600 Subject: [PATCH 04/13] Moves Segment Sampler and Scheduler to Auto Segment Refinement popup --- src/wwwroot/js/genpage/gentab/prompttools.js | 67 +++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/wwwroot/js/genpage/gentab/prompttools.js b/src/wwwroot/js/genpage/gentab/prompttools.js index b70a8e77f..b59b5dacb 100644 --- a/src/wwwroot/js/genpage/gentab/prompttools.js +++ b/src/wwwroot/js/genpage/gentab/prompttools.js @@ -403,6 +403,10 @@ class PromptPlusButton { this.segmentModalOther.innerHTML = makeGenericPopover('text_prompt_segment_model', 'Prompt Syntax: Segment Model', 'Model', "What model to find the segment with.\nBy default, CLIP-Seg is a special model that uses text prompt matching.\nYou may instead use a YOLOv8 model.", '') + makeDropdownInput(null, 'text_prompt_segment_model', '', 'Segment Model', '', ['CLIP-Seg'], 'CLIP-Seg', false, true, ['CLIP-Seg (Match by prompting)']) + + makeGenericPopover('text_prompt_segment_sampler', 'Segment Sampler', 'Sampler', "Sampler to use for the segment stage.", '') + + makeDropdownInput(null, 'text_prompt_segment_sampler', '', 'Sampler', '', [], '', true, true, []) + + makeGenericPopover('text_prompt_segment_scheduler', 'Segment Scheduler', 'Scheduler', "Scheduler to use for the segment stage.", '') + + makeDropdownInput(null, 'text_prompt_segment_scheduler', '', 'Scheduler', '', [], '', true, true, []) + makeGenericPopover('text_prompt_segment_textmatch', 'Prompt Syntax: Segment Text Match', 'Text', "The text to match against in the image.\nDoesn't apply when using a YOLO model.\nFor example, 'face' or 'the man's face'", '') + makeTextInput(null, 'text_prompt_segment_textmatch', '', 'Text Match', '', '', 'normal', '', false, false, true) + makeGenericPopover('text_prompt_segment_yoloid', 'Prompt Syntax: Segment YOLO ID', 'Number', 'The ID of the match within the YOLO result to use.\nDefault of 0 means all matches.\nIf you set to 1, it will use the first match it finds (eg the first face in a group of faces).', '') @@ -418,6 +422,8 @@ class PromptPlusButton { + makeGenericPopover('text_prompt_segment_gentext', 'Prompt Syntax: Segment Generation Prompt', 'text', 'The prompt to use when regenerating the matched area.\nShould be a full text on its own, can use a subset of general prompting syntax.', '') + makeTextInput(null, 'text_prompt_segment_gentext', '', 'Generation Prompt', '', '', 'prompt', 'Type your generation prompt here...', false, false, true); this.segmentModalModelSelect = getRequiredElementById('text_prompt_segment_model'); + this.segmentModalSampler = getRequiredElementById('text_prompt_segment_sampler'); + this.segmentModalScheduler = getRequiredElementById('text_prompt_segment_scheduler'); this.segmentModalModelSelect.addEventListener('change', () => this.segmentModalProcessChanges()); this.segmentModalTextMatch = getRequiredElementById('text_prompt_segment_textmatch'); this.segmentModalClassIds = getRequiredElementById('text_prompt_segment_classids'); @@ -428,6 +434,7 @@ class PromptPlusButton { this.segmentModalMainText = getRequiredElementById('text_prompt_segment_gentext'); textPromptAddKeydownHandler(this.segmentModalMainText); enableSlidersIn(this.segmentModalOther); + this.populateSegmentSamplerScheduler(); this.regionModalOther = getRequiredElementById('text_prompt_region_other_inputs'); this.regionModalOther.innerHTML = makeGenericPopover('text_prompt_region_x', 'Prompt Syntax: Region Left X', 'Left X', "The left X coordinate of the region's box.", '') @@ -532,6 +539,7 @@ class PromptPlusButton { this.segmentModalModelSelect.innerHTML = html; this.segmentModalModelSelect.value = 'CLIP-Seg'; this.segmentModalMainText.value = ''; + this.populateSegmentSamplerScheduler(); this.segmentModalCreativity.value = 0.6; this.segmentModalThreshold.value = 0.5; this.segmentModalTextMatch.value = ''; @@ -573,7 +581,64 @@ class PromptPlusButton { } } $('#text_prompt_segment_modal').modal('hide'); - this.applyNewSyntax(` ${this.segmentModalMainText.value.trim()}`); + let prepend = ''; + if (this.segmentModalSampler && !this.segmentModalSampler.classList.contains('disabled-input') && !this.segmentModalSampler.disabled && this.segmentModalSampler.value) { + prepend += ` `; + } + if (this.segmentModalScheduler && !this.segmentModalScheduler.classList.contains('disabled-input') && !this.segmentModalScheduler.disabled && this.segmentModalScheduler.value) { + prepend += ` `; + } + this.applyNewSyntax(`${prepend} ${this.segmentModalMainText.value.trim()}`); + + } + + populateSegmentSamplerScheduler() { + try { + // Helper to clone options from an existing select into our modal select + let copyOptions = (sourceId, destSelect) => { + if (!destSelect) { + return; + } + let cur = destSelect.value || ''; + destSelect.innerHTML = ''; + let src = document.getElementById(sourceId); + if (src && src.options && src.options.length) { + for (let i = 0; i < src.options.length; i++) { + let srcOpt = src.options[i]; + let opt = document.createElement('option'); + opt.value = srcOpt.value; + opt.textContent = srcOpt.textContent; + destSelect.appendChild(opt); + } + } + // Restore selection if still valid, else leave first option selected + let values = Array.from(destSelect.options).map(o => o.value); + destSelect.value = values.includes(cur) ? cur : (destSelect.options.length > 0 ? destSelect.options[0].value : ''); + }; + copyOptions('input_sampler', this.segmentModalSampler); + copyOptions('input_scheduler', this.segmentModalScheduler); + if (this.segmentModalSampler) { + let samplerToggle = document.getElementById('text_prompt_segment_sampler_toggle'); + if (samplerToggle && (!samplerToggle.checked || samplerToggle.disabled)) { + this.segmentModalSampler.classList.add('disabled-input'); + } + else { + this.segmentModalSampler.classList.remove('disabled-input'); + } + } + if (this.segmentModalScheduler) { + let schedulerToggle = document.getElementById('text_prompt_segment_scheduler_toggle'); + if (schedulerToggle && (!schedulerToggle.checked || schedulerToggle.disabled)) { + this.segmentModalScheduler.classList.add('disabled-input'); + } + else { + this.segmentModalScheduler.classList.remove('disabled-input'); + } + } + } + catch (e) { + // Safe guard: don't break UI if globals not ready + } } regionModalClear() { From ec95065855b04396dc7c79bc0607d32a3d4a2743 Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Fri, 7 Nov 2025 16:53:44 -0600 Subject: [PATCH 05/13] Appends segment sampler/scheduler --- src/wwwroot/js/genpage/gentab/prompttools.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wwwroot/js/genpage/gentab/prompttools.js b/src/wwwroot/js/genpage/gentab/prompttools.js index b59b5dacb..2f29221ca 100644 --- a/src/wwwroot/js/genpage/gentab/prompttools.js +++ b/src/wwwroot/js/genpage/gentab/prompttools.js @@ -581,14 +581,14 @@ class PromptPlusButton { } } $('#text_prompt_segment_modal').modal('hide'); - let prepend = ''; + let append = ''; if (this.segmentModalSampler && !this.segmentModalSampler.classList.contains('disabled-input') && !this.segmentModalSampler.disabled && this.segmentModalSampler.value) { - prepend += ` `; + append += ` `; } if (this.segmentModalScheduler && !this.segmentModalScheduler.classList.contains('disabled-input') && !this.segmentModalScheduler.disabled && this.segmentModalScheduler.value) { - prepend += ` `; + append += ` `; } - this.applyNewSyntax(`${prepend} ${this.segmentModalMainText.value.trim()}`); + this.applyNewSyntax(` ${this.segmentModalMainText.value.trim()}${append}`); } From 0556a609e5f0c7bd3d4cc2ee6476eeef52f2e5cb Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Fri, 7 Nov 2025 16:55:17 -0600 Subject: [PATCH 06/13] Adds space to left when appending --- src/wwwroot/js/genpage/gentab/prompttools.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wwwroot/js/genpage/gentab/prompttools.js b/src/wwwroot/js/genpage/gentab/prompttools.js index 2f29221ca..f81390c10 100644 --- a/src/wwwroot/js/genpage/gentab/prompttools.js +++ b/src/wwwroot/js/genpage/gentab/prompttools.js @@ -583,10 +583,10 @@ class PromptPlusButton { $('#text_prompt_segment_modal').modal('hide'); let append = ''; if (this.segmentModalSampler && !this.segmentModalSampler.classList.contains('disabled-input') && !this.segmentModalSampler.disabled && this.segmentModalSampler.value) { - append += ` `; + append += ` `; } if (this.segmentModalScheduler && !this.segmentModalScheduler.classList.contains('disabled-input') && !this.segmentModalScheduler.disabled && this.segmentModalScheduler.value) { - append += ` `; + append += ` `; } this.applyNewSyntax(` ${this.segmentModalMainText.value.trim()}${append}`); From 914c5ed1d1bb9386917ad6fbe300299cc0860525 Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Fri, 7 Nov 2025 17:04:24 -0600 Subject: [PATCH 07/13] Move Segment sampler/scheduler insertion to right after tag --- src/wwwroot/js/genpage/gentab/prompttools.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wwwroot/js/genpage/gentab/prompttools.js b/src/wwwroot/js/genpage/gentab/prompttools.js index f81390c10..b1441a45c 100644 --- a/src/wwwroot/js/genpage/gentab/prompttools.js +++ b/src/wwwroot/js/genpage/gentab/prompttools.js @@ -583,12 +583,12 @@ class PromptPlusButton { $('#text_prompt_segment_modal').modal('hide'); let append = ''; if (this.segmentModalSampler && !this.segmentModalSampler.classList.contains('disabled-input') && !this.segmentModalSampler.disabled && this.segmentModalSampler.value) { - append += ` `; + append += ``; } if (this.segmentModalScheduler && !this.segmentModalScheduler.classList.contains('disabled-input') && !this.segmentModalScheduler.disabled && this.segmentModalScheduler.value) { - append += ` `; + append += ``; } - this.applyNewSyntax(` ${this.segmentModalMainText.value.trim()}${append}`); + this.applyNewSyntax(`${append} ${this.segmentModalMainText.value.trim()}`); } From cc2aa2fa8450db8b6f2a72159ca3f731a54e49fd Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Sat, 8 Nov 2025 08:40:34 -0600 Subject: [PATCH 08/13] Simplify code; user "scheduler" and "sampler" --- src/wwwroot/js/genpage/gentab/prompttools.js | 58 +++++++------------- 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/src/wwwroot/js/genpage/gentab/prompttools.js b/src/wwwroot/js/genpage/gentab/prompttools.js index b1441a45c..da1e658d3 100644 --- a/src/wwwroot/js/genpage/gentab/prompttools.js +++ b/src/wwwroot/js/genpage/gentab/prompttools.js @@ -583,10 +583,10 @@ class PromptPlusButton { $('#text_prompt_segment_modal').modal('hide'); let append = ''; if (this.segmentModalSampler && !this.segmentModalSampler.classList.contains('disabled-input') && !this.segmentModalSampler.disabled && this.segmentModalSampler.value) { - append += ``; + append += ``; } if (this.segmentModalScheduler && !this.segmentModalScheduler.classList.contains('disabled-input') && !this.segmentModalScheduler.disabled && this.segmentModalScheduler.value) { - append += ``; + append += ``; } this.applyNewSyntax(`${append} ${this.segmentModalMainText.value.trim()}`); @@ -594,50 +594,34 @@ class PromptPlusButton { populateSegmentSamplerScheduler() { try { - // Helper to clone options from an existing select into our modal select - let copyOptions = (sourceId, destSelect) => { - if (!destSelect) { + let setupDropdown = (sourceId, destSelect, targetId) => { + let src = document.getElementById(sourceId); + if (!destSelect || !src || !src.options || !src.options.length) { return; } - let cur = destSelect.value || ''; + destSelect.innerHTML = ''; - let src = document.getElementById(sourceId); - if (src && src.options && src.options.length) { - for (let i = 0; i < src.options.length; i++) { - let srcOpt = src.options[i]; - let opt = document.createElement('option'); - opt.value = srcOpt.value; - opt.textContent = srcOpt.textContent; - destSelect.appendChild(opt); - } + for (let i = 0; i < src.options.length; i++) { + let srcOpt = src.options[i]; + let opt = document.createElement('option'); + opt.value = srcOpt.value; + opt.textContent = srcOpt.textContent; + destSelect.appendChild(opt); } - // Restore selection if still valid, else leave first option selected - let values = Array.from(destSelect.options).map(o => o.value); - destSelect.value = values.includes(cur) ? cur : (destSelect.options.length > 0 ? destSelect.options[0].value : ''); - }; - copyOptions('input_sampler', this.segmentModalSampler); - copyOptions('input_scheduler', this.segmentModalScheduler); - if (this.segmentModalSampler) { - let samplerToggle = document.getElementById('text_prompt_segment_sampler_toggle'); - if (samplerToggle && (!samplerToggle.checked || samplerToggle.disabled)) { - this.segmentModalSampler.classList.add('disabled-input'); - } - else { - this.segmentModalSampler.classList.remove('disabled-input'); - } - } - if (this.segmentModalScheduler) { - let schedulerToggle = document.getElementById('text_prompt_segment_scheduler_toggle'); - if (schedulerToggle && (!schedulerToggle.checked || schedulerToggle.disabled)) { - this.segmentModalScheduler.classList.add('disabled-input'); + + let targetToggler = document.getElementById(targetId); + if (targetToggler && (!targetToggler.checked || targetToggler.disabled)) { + destSelect.classList.add('disabled-input'); } else { - this.segmentModalScheduler.classList.remove('disabled-input'); + destSelect.classList.remove('disabled-input'); } - } + }; + + setupDropdown('input_sampler', this.segmentModalSampler, 'text_prompt_segment_sampler_toggle'); + setupDropdown('input_scheduler', this.segmentModalScheduler, 'text_prompt_segment_scheduler_toggle'); } catch (e) { - // Safe guard: don't break UI if globals not ready } } From 740f16c27759e979120f278755062204599c04ea Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Mon, 10 Nov 2025 11:43:47 -0600 Subject: [PATCH 09/13] CR feedback --- .../ComfyUIBackend/ComfyUIBackendExtension.cs | 10 +--- .../ComfyUIBackend/WorkflowGeneratorSteps.cs | 4 +- src/Text2Image/T2IParamTypes.cs | 4 +- src/wwwroot/js/genpage/gentab/prompttools.js | 51 ++++++++----------- 4 files changed, 27 insertions(+), 42 deletions(-) diff --git a/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs b/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs index f0d626a0c..33b8ff361 100644 --- a/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs +++ b/src/BuiltinExtensions/ComfyUIBackend/ComfyUIBackendExtension.cs @@ -607,7 +607,7 @@ public static void AssignValuesFromRaw(JObject rawObjectInfo) } } - public static T2IRegisteredParam CustomWorkflowParam, SamplerParam, SchedulerParam, RefinerSamplerParam, RefinerSchedulerParam, SegmentSamplerParam, SegmentSchedulerParam, RefinerUpscaleMethod, UseIPAdapterForRevision, IPAdapterWeightType, VideoPreviewType, VideoFrameInterpolationMethod, Text2VideoFrameInterpolationMethod, GligenModel, YoloModelInternal, PreferredDType, UseStyleModel, TeaCacheMode, EasyCacheMode, SetClipDevice; + public static T2IRegisteredParam CustomWorkflowParam, SamplerParam, SchedulerParam, RefinerSamplerParam, RefinerSchedulerParam, RefinerUpscaleMethod, UseIPAdapterForRevision, IPAdapterWeightType, VideoPreviewType, VideoFrameInterpolationMethod, Text2VideoFrameInterpolationMethod, GligenModel, YoloModelInternal, PreferredDType, UseStyleModel, TeaCacheMode, EasyCacheMode, SetClipDevice; public static T2IRegisteredParam AITemplateParam, DebugRegionalPrompting, ShiftedLatentAverageInit, UseCfgZeroStar, UseTCFG; @@ -728,14 +728,6 @@ public override void OnInit() "normal", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupRefinerOverrides, OrderPriority: -1.5, GetValues: (_) => Schedulers )); - SegmentSamplerParam = T2IParamTypes.Register(new("Segment Sampler", SamplerParam.Type.Description + "\nThis is an override to only affect the Segment stage.", - "euler", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupSegmentOverrides, OrderPriority: 2.3, VisibleNormally: false, - GetValues: (_) => Samplers - )); - SegmentSchedulerParam = T2IParamTypes.Register(new("Segment Scheduler", SchedulerParam.Type.Description + "\nThis is an override to only affect the Segment stage.", - "normal", Toggleable: true, FeatureFlag: "comfyui", Group: T2IParamTypes.GroupSegmentOverrides, OrderPriority: 2.4, VisibleNormally: false, - GetValues: (_) => Schedulers - )); for (int i = 0; i < 3; i++) { ControlNetPreprocessorParams[i] = T2IParamTypes.Register(new($"ControlNet{T2IParamTypes.Controlnets[i].NameSuffix} Preprocessor", "The preprocessor to use on the ControlNet input image.\nIf toggled off, will be automatically selected.\nUse 'None' to disable preprocessing.", diff --git a/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs b/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs index 537547b62..973261ece 100644 --- a/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs +++ b/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs @@ -1501,8 +1501,8 @@ JArray doMaskShrinkApply(WorkflowGenerator g, JArray imgIn) int startStep = (int)Math.Round(steps * (1 - part.Strength2)); long seed = g.UserInput.Get(T2IParamTypes.Seed) + 2 + i; double cfg = g.UserInput.GetNullable(T2IParamTypes.CFGScale, part.ContextID, false) ?? g.UserInput.GetNullable(T2IParamTypes.SegmentCFGScale, part.ContextID) ?? g.UserInput.GetNullable(T2IParamTypes.RefinerCFGScale, part.ContextID) ?? g.UserInput.Get(T2IParamTypes.CFGScale, 7, sectionId: part.ContextID); - string explicitSampler = g.UserInput.Get(ComfyUIBackendExtension.SamplerParam, null, sectionId: part.ContextID, includeBase: false) ?? g.UserInput.Get(ComfyUIBackendExtension.SegmentSamplerParam, null); - string explicitScheduler = g.UserInput.Get(ComfyUIBackendExtension.SchedulerParam, null, sectionId: part.ContextID, includeBase: false) ?? g.UserInput.Get(ComfyUIBackendExtension.SegmentSchedulerParam, null); + string explicitSampler = g.UserInput.Get(ComfyUIBackendExtension.SamplerParam, null, sectionId: part.ContextID, includeBase: false); + string explicitScheduler = g.UserInput.Get(ComfyUIBackendExtension.SchedulerParam, null, sectionId: part.ContextID, includeBase: false); string sampler = g.CreateKSampler(model, prompt, negPrompt, [g.MaskShrunkInfo.MaskedLatent, 0], cfg, steps, startStep, 10000, seed, false, true, explicitSampler: explicitSampler, explicitScheduler: explicitScheduler, sectionId: part.ContextID); string decoded = g.CreateVAEDecode(vae, [sampler, 0]); g.FinalImageOut = g.RecompositeCropped(g.MaskShrunkInfo.BoundsNode, [g.MaskShrunkInfo.CroppedMask, 0], g.FinalImageOut, [decoded, 0]); diff --git a/src/Text2Image/T2IParamTypes.cs b/src/Text2Image/T2IParamTypes.cs index a6fc5b664..04505a0e7 100644 --- a/src/Text2Image/T2IParamTypes.cs +++ b/src/Text2Image/T2IParamTypes.cs @@ -801,11 +801,11 @@ static List listVaes(Session s) "", Toggleable: true, Subtype: "Stable-Diffusion", Group: GroupSegmentOverrides, OrderPriority: 2, IsAdvanced: true )); SegmentSteps = Register(new("Segment Steps", "Alternate Steps value for when calculating the segment stage.\nThis replaces the 'Steps' total count before calculating the Segment Creativity.", - "40", Min: 1, Max: 200, ViewMax: 100, Step: 1, Examples: ["20", "40", "60"], OrderPriority: 2.1, Toggleable: true, IsAdvanced: true, Group: GroupSegmentOverrides, ViewType: ParamViewType.SLIDER + "40", Min: 1, Max: 200, ViewMax: 100, Step: 1, Examples: ["20", "40", "60"], OrderPriority: 4, Toggleable: true, IsAdvanced: true, Group: GroupSegmentOverrides, ViewType: ParamViewType.SLIDER )); SegmentCFGScale = Register(new("Segment CFG Scale", "For the segment model independently of the base model, how strongly to scale prompt input.\nHigher CFG scales tend to produce more contrast, and lower CFG scales produce less contrast.\n" + "Too-high values can cause corrupted/burnt images, too-low can cause nonsensical images.\n7 is a good baseline. Normal usages vary between 4 and 9.\nSome model types, such as Turbo, expect CFG around 1.", - "7", Min: 0, Max: 100, ViewMax: 20, Step: 0.5, Examples: ["5", "6", "7", "8", "9"], OrderPriority: 2.2, ViewType: ParamViewType.SLIDER, Group: GroupSegmentOverrides, ChangeWeight: -3, Toggleable: true, IsAdvanced: true + "7", Min: 0, Max: 100, ViewMax: 20, Step: 0.5, Examples: ["5", "6", "7", "8", "9"], OrderPriority: 5, ViewType: ParamViewType.SLIDER, Group: GroupSegmentOverrides, ChangeWeight: -3, Toggleable: true, IsAdvanced: true )); // ================================================ Advanced Sampling ================================================ GroupAdvancedSampling = new("Advanced Sampling", Open: false, OrderPriority: 15, IsAdvanced: true); diff --git a/src/wwwroot/js/genpage/gentab/prompttools.js b/src/wwwroot/js/genpage/gentab/prompttools.js index da1e658d3..77d5e2c93 100644 --- a/src/wwwroot/js/genpage/gentab/prompttools.js +++ b/src/wwwroot/js/genpage/gentab/prompttools.js @@ -434,7 +434,8 @@ class PromptPlusButton { this.segmentModalMainText = getRequiredElementById('text_prompt_segment_gentext'); textPromptAddKeydownHandler(this.segmentModalMainText); enableSlidersIn(this.segmentModalOther); - this.populateSegmentSamplerScheduler(); + this.populateDropdownFromSource('input_sampler', this.segmentModalSampler, 'text_prompt_segment_sampler_toggle'); + this.populateDropdownFromSource('input_scheduler', this.segmentModalScheduler, 'text_prompt_segment_scheduler_toggle'); this.regionModalOther = getRequiredElementById('text_prompt_region_other_inputs'); this.regionModalOther.innerHTML = makeGenericPopover('text_prompt_region_x', 'Prompt Syntax: Region Left X', 'Left X', "The left X coordinate of the region's box.", '') @@ -539,7 +540,8 @@ class PromptPlusButton { this.segmentModalModelSelect.innerHTML = html; this.segmentModalModelSelect.value = 'CLIP-Seg'; this.segmentModalMainText.value = ''; - this.populateSegmentSamplerScheduler(); + this.populateDropdownFromSource('input_sampler', this.segmentModalSampler, 'text_prompt_segment_sampler_toggle'); + this.populateDropdownFromSource('input_scheduler', this.segmentModalScheduler, 'text_prompt_segment_scheduler_toggle'); this.segmentModalCreativity.value = 0.6; this.segmentModalThreshold.value = 0.5; this.segmentModalTextMatch.value = ''; @@ -592,36 +594,27 @@ class PromptPlusButton { } - populateSegmentSamplerScheduler() { - try { - let setupDropdown = (sourceId, destSelect, targetId) => { - let src = document.getElementById(sourceId); - if (!destSelect || !src || !src.options || !src.options.length) { - return; - } - - destSelect.innerHTML = ''; - for (let i = 0; i < src.options.length; i++) { - let srcOpt = src.options[i]; - let opt = document.createElement('option'); - opt.value = srcOpt.value; - opt.textContent = srcOpt.textContent; - destSelect.appendChild(opt); - } + populateDropdownFromSource(sourceId, destSelect, targetId) { + let src = document.getElementById(sourceId); + if (!destSelect || !src || !src.options || !src.options.length) { + return; + } - let targetToggler = document.getElementById(targetId); - if (targetToggler && (!targetToggler.checked || targetToggler.disabled)) { - destSelect.classList.add('disabled-input'); - } - else { - destSelect.classList.remove('disabled-input'); - } - }; + destSelect.innerHTML = ''; + for (let i = 0; i < src.options.length; i++) { + let srcOpt = src.options[i]; + let opt = document.createElement('option'); + opt.value = srcOpt.value; + opt.textContent = srcOpt.textContent; + destSelect.appendChild(opt); + } - setupDropdown('input_sampler', this.segmentModalSampler, 'text_prompt_segment_sampler_toggle'); - setupDropdown('input_scheduler', this.segmentModalScheduler, 'text_prompt_segment_scheduler_toggle'); + let targetToggler = document.getElementById(targetId); + if (targetToggler && (!targetToggler.checked || targetToggler.disabled)) { + destSelect.classList.add('disabled-input'); } - catch (e) { + else { + destSelect.classList.remove('disabled-input'); } } From 5a0b4fcba9697722ab9f81bcfa358acb02b6e5e3 Mon Sep 17 00:00:00 2001 From: Juan Treminio Date: Wed, 12 Nov 2025 09:30:50 -0600 Subject: [PATCH 10/13] Revert change --- .../ComfyUIBackend/WorkflowGeneratorSteps.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs b/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs index 973261ece..ecdc2e35e 100644 --- a/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs +++ b/src/BuiltinExtensions/ComfyUIBackend/WorkflowGeneratorSteps.cs @@ -1501,9 +1501,7 @@ JArray doMaskShrinkApply(WorkflowGenerator g, JArray imgIn) int startStep = (int)Math.Round(steps * (1 - part.Strength2)); long seed = g.UserInput.Get(T2IParamTypes.Seed) + 2 + i; double cfg = g.UserInput.GetNullable(T2IParamTypes.CFGScale, part.ContextID, false) ?? g.UserInput.GetNullable(T2IParamTypes.SegmentCFGScale, part.ContextID) ?? g.UserInput.GetNullable(T2IParamTypes.RefinerCFGScale, part.ContextID) ?? g.UserInput.Get(T2IParamTypes.CFGScale, 7, sectionId: part.ContextID); - string explicitSampler = g.UserInput.Get(ComfyUIBackendExtension.SamplerParam, null, sectionId: part.ContextID, includeBase: false); - string explicitScheduler = g.UserInput.Get(ComfyUIBackendExtension.SchedulerParam, null, sectionId: part.ContextID, includeBase: false); - string sampler = g.CreateKSampler(model, prompt, negPrompt, [g.MaskShrunkInfo.MaskedLatent, 0], cfg, steps, startStep, 10000, seed, false, true, explicitSampler: explicitSampler, explicitScheduler: explicitScheduler, sectionId: part.ContextID); + string sampler = g.CreateKSampler(model, prompt, negPrompt, [g.MaskShrunkInfo.MaskedLatent, 0], cfg, steps, startStep, 10000, seed, false, true, sectionId: part.ContextID); string decoded = g.CreateVAEDecode(vae, [sampler, 0]); g.FinalImageOut = g.RecompositeCropped(g.MaskShrunkInfo.BoundsNode, [g.MaskShrunkInfo.CroppedMask, 0], g.FinalImageOut, [decoded, 0]); g.MaskShrunkInfo = new(null, null, null, null); From 0f7cee1a182b28cf2a3b05980ec8cd3841a76339 Mon Sep 17 00:00:00 2001 From: "Alex \"mcmonkey\" Goodwin" Date: Wed, 12 Nov 2025 11:39:28 -0800 Subject: [PATCH 11/13] fixes --- src/wwwroot/js/genpage/gentab/prompttools.js | 25 ++++++++------------ 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/wwwroot/js/genpage/gentab/prompttools.js b/src/wwwroot/js/genpage/gentab/prompttools.js index 17e13ce48..54d1eca15 100644 --- a/src/wwwroot/js/genpage/gentab/prompttools.js +++ b/src/wwwroot/js/genpage/gentab/prompttools.js @@ -435,7 +435,9 @@ class PromptPlusButton { + makeTextInput(null, 'text_prompt_segment_gentext', '', 'Generation Prompt', '', '', 'prompt', 'Type your generation prompt here...', false, false, true); this.segmentModalModelSelect = getRequiredElementById('text_prompt_segment_model'); this.segmentModalSampler = getRequiredElementById('text_prompt_segment_sampler'); + doToggleEnable('text_prompt_segment_sampler'); this.segmentModalScheduler = getRequiredElementById('text_prompt_segment_scheduler'); + doToggleEnable('text_prompt_segment_scheduler'); this.segmentModalModelSelect.addEventListener('change', () => this.segmentModalProcessChanges()); this.segmentModalTextMatch = getRequiredElementById('text_prompt_segment_textmatch'); this.segmentModalClassIds = getRequiredElementById('text_prompt_segment_classids'); @@ -560,6 +562,10 @@ class PromptPlusButton { this.segmentModalYoloId.value = 0; this.segmentModalClassIds.value = ''; this.segmentModalInvertMask.checked = false; + getRequiredElementById('text_prompt_segment_sampler_toggle').checked = false; + doToggleEnable('text_prompt_segment_sampler'); + getRequiredElementById('text_prompt_segment_scheduler_toggle').checked = false; + doToggleEnable('text_prompt_segment_scheduler'); triggerChangeFor(this.segmentModalCreativity); triggerChangeFor(this.segmentModalThreshold); } @@ -596,38 +602,27 @@ class PromptPlusButton { } $('#text_prompt_segment_modal').modal('hide'); let append = ''; - if (this.segmentModalSampler && !this.segmentModalSampler.classList.contains('disabled-input') && !this.segmentModalSampler.disabled && this.segmentModalSampler.value) { + if (this.segmentModalSampler && !this.segmentModalSampler.classList.contains('disabled-input')) { append += ``; } - if (this.segmentModalScheduler && !this.segmentModalScheduler.classList.contains('disabled-input') && !this.segmentModalScheduler.disabled && this.segmentModalScheduler.value) { + if (this.segmentModalScheduler && !this.segmentModalScheduler.classList.contains('disabled-input')) { append += ``; } this.applyNewSyntax(`${append} ${this.segmentModalMainText.value.trim()}`); - } populateDropdownFromSource(sourceId, destSelect, targetId) { let src = document.getElementById(sourceId); - if (!destSelect || !src || !src.options || !src.options.length) { + if (!destSelect || !src || !src.options) { return; } - destSelect.innerHTML = ''; - for (let i = 0; i < src.options.length; i++) { - let srcOpt = src.options[i]; + for (let srcOpt of src.options) { let opt = document.createElement('option'); opt.value = srcOpt.value; opt.textContent = srcOpt.textContent; destSelect.appendChild(opt); } - - let targetToggler = document.getElementById(targetId); - if (targetToggler && (!targetToggler.checked || targetToggler.disabled)) { - destSelect.classList.add('disabled-input'); - } - else { - destSelect.classList.remove('disabled-input'); - } } regionModalClear() { From cb3b5f8a34e67d7ddea7fae11386c24d456932a6 Mon Sep 17 00:00:00 2001 From: "Alex \"mcmonkey\" Goodwin" Date: Wed, 12 Nov 2025 11:42:44 -0800 Subject: [PATCH 12/13] reorder --- src/wwwroot/js/genpage/gentab/prompttools.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wwwroot/js/genpage/gentab/prompttools.js b/src/wwwroot/js/genpage/gentab/prompttools.js index 54d1eca15..2a3129270 100644 --- a/src/wwwroot/js/genpage/gentab/prompttools.js +++ b/src/wwwroot/js/genpage/gentab/prompttools.js @@ -415,10 +415,6 @@ class PromptPlusButton { this.segmentModalOther.innerHTML = makeGenericPopover('text_prompt_segment_model', 'Prompt Syntax: Segment Model', 'Model', "What model to find the segment with.\nBy default, CLIP-Seg is a special model that uses text prompt matching.\nYou may instead use a YOLOv8 model.", '') + makeDropdownInput(null, 'text_prompt_segment_model', '', 'Segment Model', '', ['CLIP-Seg'], 'CLIP-Seg', false, true, ['CLIP-Seg (Match by prompting)']) - + makeGenericPopover('text_prompt_segment_sampler', 'Segment Sampler', 'Sampler', "Sampler to use for the segment stage.", '') - + makeDropdownInput(null, 'text_prompt_segment_sampler', '', 'Sampler', '', [], '', true, true, []) - + makeGenericPopover('text_prompt_segment_scheduler', 'Segment Scheduler', 'Scheduler', "Scheduler to use for the segment stage.", '') - + makeDropdownInput(null, 'text_prompt_segment_scheduler', '', 'Scheduler', '', [], '', true, true, []) + makeGenericPopover('text_prompt_segment_textmatch', 'Prompt Syntax: Segment Text Match', 'Text', "The text to match against in the image.\nDoesn't apply when using a YOLO model.\nFor example, 'face' or 'the man's face'", '') + makeTextInput(null, 'text_prompt_segment_textmatch', '', 'Text Match', '', '', 'normal', '', false, false, true) + makeGenericPopover('text_prompt_segment_yoloid', 'Prompt Syntax: Segment YOLO ID', 'Number', 'The ID of the match within the YOLO result to use.\nDefault of 0 means all matches.\nIf you set to 1, it will use the first match it finds (eg the first face in a group of faces).', '') @@ -432,7 +428,11 @@ class PromptPlusButton { + makeGenericPopover('text_prompt_segment_invert_mask', 'Prompt Syntax: Segment Invert Mask', 'Checkbox', 'Whether to invert the mask.\nIf checked, select everything except what was matched by the model.', '') + makeCheckboxInput(null, 'text_prompt_segment_invert_mask', '', 'Invert Mask', '', false, false, false, true) + makeGenericPopover('text_prompt_segment_gentext', 'Prompt Syntax: Segment Generation Prompt', 'text', 'The prompt to use when regenerating the matched area.\nShould be a full text on its own, can use a subset of general prompting syntax.', '') - + makeTextInput(null, 'text_prompt_segment_gentext', '', 'Generation Prompt', '', '', 'prompt', 'Type your generation prompt here...', false, false, true); + + makeTextInput(null, 'text_prompt_segment_gentext', '', 'Generation Prompt', '', '', 'prompt', 'Type your generation prompt here...', false, false, true) + + makeGenericPopover('text_prompt_segment_sampler', 'Segment Sampler', 'Sampler', 'Optional alternate sampler to use when regenerating the matched area.\nIf unset, the main sampler param will be used.', '') + + makeDropdownInput(null, 'text_prompt_segment_sampler', '', 'Sampler', '', [], '', true, true, []) + + makeGenericPopover('text_prompt_segment_scheduler', 'Segment Scheduler', 'Scheduler', 'Optional alternate scheduler to use when regenerating the matched area.\nIf unset, the main scheduler param will be used.', '') + + makeDropdownInput(null, 'text_prompt_segment_scheduler', '', 'Scheduler', '', [], '', true, true, []); this.segmentModalModelSelect = getRequiredElementById('text_prompt_segment_model'); this.segmentModalSampler = getRequiredElementById('text_prompt_segment_sampler'); doToggleEnable('text_prompt_segment_sampler'); From 7ec72951490bd8cf0ffcef85ad8a39d8d25618b7 Mon Sep 17 00:00:00 2001 From: "Alex \"mcmonkey\" Goodwin" Date: Wed, 12 Nov 2025 11:43:40 -0800 Subject: [PATCH 13/13] missed data copy --- src/wwwroot/js/genpage/gentab/prompttools.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wwwroot/js/genpage/gentab/prompttools.js b/src/wwwroot/js/genpage/gentab/prompttools.js index 2a3129270..b4f23ea14 100644 --- a/src/wwwroot/js/genpage/gentab/prompttools.js +++ b/src/wwwroot/js/genpage/gentab/prompttools.js @@ -621,6 +621,9 @@ class PromptPlusButton { let opt = document.createElement('option'); opt.value = srcOpt.value; opt.textContent = srcOpt.textContent; + if (srcOpt.dataset.cleanname) { + opt.dataset.cleanname = srcOpt.dataset.cleanname; + } destSelect.appendChild(opt); } }