comfy-diffusion 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,383 @@
1
+ """Sampling helpers that wrap ComfyUI's KSampler behavior."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+
8
+ def _get_common_ksampler() -> Any:
9
+ """Resolve ComfyUI sampling entrypoint at call time."""
10
+ from ._runtime import ensure_comfyui_on_path
11
+
12
+ ensure_comfyui_on_path()
13
+ import nodes
14
+
15
+ return nodes.common_ksampler
16
+
17
+
18
+ def _get_basic_guider_type() -> Any:
19
+ """Resolve ComfyUI BasicGuider implementation at call time."""
20
+ from ._runtime import ensure_comfyui_on_path
21
+
22
+ ensure_comfyui_on_path()
23
+ from comfy_extras.nodes_custom_sampler import Guider_Basic
24
+
25
+ return Guider_Basic
26
+
27
+
28
+ def _get_cfg_guider_type() -> Any:
29
+ """Resolve ComfyUI CFGGuider implementation at call time."""
30
+ from ._runtime import ensure_comfyui_on_path
31
+
32
+ ensure_comfyui_on_path()
33
+ from comfy.samplers import CFGGuider
34
+
35
+ return CFGGuider
36
+
37
+
38
+ def _get_random_noise_type() -> Any:
39
+ """Resolve ComfyUI RandomNoise implementation at call time."""
40
+ from ._runtime import ensure_comfyui_on_path
41
+
42
+ ensure_comfyui_on_path()
43
+ from comfy_extras.nodes_custom_sampler import RandomNoise
44
+
45
+ return RandomNoise
46
+
47
+
48
+ def _get_disable_noise_type() -> Any:
49
+ """Resolve ComfyUI DisableNoise implementation at call time."""
50
+ from ._runtime import ensure_comfyui_on_path
51
+
52
+ ensure_comfyui_on_path()
53
+ from comfy_extras.nodes_custom_sampler import DisableNoise
54
+
55
+ return DisableNoise
56
+
57
+
58
+ def _get_basic_scheduler_type() -> Any:
59
+ """Resolve ComfyUI BasicScheduler implementation at call time."""
60
+ from ._runtime import ensure_comfyui_on_path
61
+
62
+ ensure_comfyui_on_path()
63
+ from comfy_extras.nodes_custom_sampler import BasicScheduler
64
+
65
+ return BasicScheduler
66
+
67
+
68
+ def _get_karras_scheduler_type() -> Any:
69
+ """Resolve ComfyUI KarrasScheduler implementation at call time."""
70
+ from ._runtime import ensure_comfyui_on_path
71
+
72
+ ensure_comfyui_on_path()
73
+ from comfy_extras.nodes_custom_sampler import KarrasScheduler
74
+
75
+ return KarrasScheduler
76
+
77
+
78
+ def _get_ays_scheduler_type() -> Any:
79
+ """Resolve ComfyUI AlignYourStepsScheduler implementation at call time."""
80
+ from ._runtime import ensure_comfyui_on_path
81
+
82
+ ensure_comfyui_on_path()
83
+ from comfy_extras.nodes_align_your_steps import AlignYourStepsScheduler
84
+
85
+ return AlignYourStepsScheduler
86
+
87
+
88
+ def _get_flux2_scheduler_type() -> Any:
89
+ """Resolve ComfyUI Flux2Scheduler implementation at call time."""
90
+ from ._runtime import ensure_comfyui_on_path
91
+
92
+ ensure_comfyui_on_path()
93
+ from comfy_extras.nodes_flux import Flux2Scheduler
94
+
95
+ return Flux2Scheduler
96
+
97
+
98
+ def _get_ltxv_scheduler_type() -> Any:
99
+ """Resolve ComfyUI LTXVScheduler implementation at call time."""
100
+ from ._runtime import ensure_comfyui_on_path
101
+
102
+ ensure_comfyui_on_path()
103
+ from comfy_extras.nodes_lt import LTXVScheduler
104
+
105
+ return LTXVScheduler
106
+
107
+
108
+ def _get_sampler_custom_advanced_type() -> Any:
109
+ """Resolve ComfyUI SamplerCustomAdvanced implementation at call time."""
110
+ from ._runtime import ensure_comfyui_on_path
111
+
112
+ ensure_comfyui_on_path()
113
+ from comfy_extras.nodes_custom_sampler import SamplerCustomAdvanced
114
+
115
+ return SamplerCustomAdvanced
116
+
117
+
118
+ def _get_split_sigmas_type() -> Any:
119
+ """Resolve ComfyUI SplitSigmas implementation at call time."""
120
+ from ._runtime import ensure_comfyui_on_path
121
+
122
+ ensure_comfyui_on_path()
123
+ from comfy_extras.nodes_custom_sampler import SplitSigmas
124
+
125
+ return SplitSigmas
126
+
127
+
128
+ def _get_split_sigmas_denoise_type() -> Any:
129
+ """Resolve ComfyUI SplitSigmasDenoise implementation at call time."""
130
+ from ._runtime import ensure_comfyui_on_path
131
+
132
+ ensure_comfyui_on_path()
133
+ from comfy_extras.nodes_custom_sampler import SplitSigmasDenoise
134
+
135
+ return SplitSigmasDenoise
136
+
137
+
138
+ def _get_ksampler_select_type() -> Any:
139
+ """Resolve ComfyUI KSamplerSelect implementation at call time."""
140
+ from ._runtime import ensure_comfyui_on_path
141
+
142
+ ensure_comfyui_on_path()
143
+ from comfy_extras.nodes_custom_sampler import KSamplerSelect
144
+
145
+ return KSamplerSelect
146
+
147
+
148
+ def _unwrap_node_output(output: Any) -> Any:
149
+ """Return the first node output value from ComfyUI V3 or tuple-style APIs."""
150
+ result = getattr(output, "result", output)
151
+ return result[0]
152
+
153
+
154
+ def basic_guider(model: Any, conditioning: Any) -> Any:
155
+ """Create a BasicGuider compatible with ``sample_custom()``."""
156
+ guider_type = _get_basic_guider_type()
157
+ guider = guider_type(model)
158
+ guider.set_conds(conditioning)
159
+ return guider
160
+
161
+
162
+ def cfg_guider(model: Any, positive: Any, negative: Any, cfg: Any) -> Any:
163
+ """Create a CFGGuider compatible with ``sample_custom()``."""
164
+ guider_type = _get_cfg_guider_type()
165
+ guider = guider_type(model)
166
+ guider.set_conds(positive, negative)
167
+ guider.set_cfg(cfg)
168
+ return guider
169
+
170
+
171
+ def random_noise(noise_seed: int) -> Any:
172
+ """Create a RandomNoise object compatible with ``sample_custom()``."""
173
+ random_noise_type = _get_random_noise_type()
174
+ return random_noise_type(noise_seed)
175
+
176
+
177
+ def disable_noise() -> Any:
178
+ """Create a DisableNoise object compatible with ``sample_custom()``."""
179
+ disable_noise_type = _get_disable_noise_type()
180
+ return disable_noise_type()
181
+
182
+
183
+ def basic_scheduler(
184
+ model: Any, scheduler_name: str, steps: int, denoise: float = 1.0
185
+ ) -> Any:
186
+ """Create SIGMAS using ComfyUI BasicScheduler."""
187
+ basic_scheduler_type = _get_basic_scheduler_type()
188
+ return _unwrap_node_output(
189
+ basic_scheduler_type.execute(model, scheduler_name, steps, denoise)
190
+ )
191
+
192
+
193
+ def karras_scheduler(
194
+ steps: int, sigma_max: float, sigma_min: float, rho: float = 7.0
195
+ ) -> Any:
196
+ """Create SIGMAS using ComfyUI KarrasScheduler."""
197
+ karras_scheduler_type = _get_karras_scheduler_type()
198
+ return _unwrap_node_output(
199
+ karras_scheduler_type.execute(steps, sigma_max, sigma_min, rho)
200
+ )
201
+
202
+
203
+ def ays_scheduler(model_type: str, steps: int, denoise: float = 1.0) -> Any:
204
+ """Create SIGMAS using ComfyUI AlignYourStepsScheduler."""
205
+ allowed_model_types = {"SD1", "SDXL", "SVD"}
206
+ if model_type not in allowed_model_types:
207
+ raise ValueError(
208
+ f"model_type must be one of {sorted(allowed_model_types)!r}; got {model_type!r}"
209
+ )
210
+
211
+ ays_scheduler_type = _get_ays_scheduler_type()
212
+ return _unwrap_node_output(ays_scheduler_type.execute(model_type, steps, denoise))
213
+
214
+
215
+ def flux2_scheduler(steps: int, width: int, height: int) -> Any:
216
+ """Create SIGMAS using ComfyUI Flux2Scheduler."""
217
+ flux2_scheduler_type = _get_flux2_scheduler_type()
218
+ return _unwrap_node_output(flux2_scheduler_type.execute(steps, width, height))
219
+
220
+
221
+ def ltxv_scheduler(
222
+ steps: int,
223
+ max_shift: float,
224
+ base_shift: float,
225
+ *,
226
+ stretch: bool = True,
227
+ terminal: float = 0.1,
228
+ latent: Any = None,
229
+ ) -> Any:
230
+ """Create SIGMAS using ComfyUI LTXVScheduler."""
231
+ ltxv_scheduler_type = _get_ltxv_scheduler_type()
232
+ return _unwrap_node_output(
233
+ ltxv_scheduler_type.execute(
234
+ steps,
235
+ max_shift,
236
+ base_shift,
237
+ stretch,
238
+ terminal,
239
+ latent,
240
+ )
241
+ )
242
+
243
+
244
+ def split_sigmas(sigmas: Any, step: int) -> tuple[Any, Any]:
245
+ """Split SIGMAS by step index using ComfyUI SplitSigmas."""
246
+ split_sigmas_type = _get_split_sigmas_type()
247
+ output = split_sigmas_type.execute(sigmas, step)
248
+ result = getattr(output, "result", output)
249
+ return result[0], result[1]
250
+
251
+
252
+ def split_sigmas_denoise(sigmas: Any, denoise: float) -> tuple[Any, Any]:
253
+ """Split SIGMAS by denoise percent using ComfyUI SplitSigmasDenoise."""
254
+ split_sigmas_denoise_type = _get_split_sigmas_denoise_type()
255
+ output = split_sigmas_denoise_type.execute(sigmas, denoise)
256
+ result = getattr(output, "result", output)
257
+ return result[0], result[1]
258
+
259
+
260
+ def get_sampler(sampler_name: str) -> Any:
261
+ """Build a SAMPLER object using ComfyUI KSamplerSelect."""
262
+ ksampler_select_type = _get_ksampler_select_type()
263
+ return _unwrap_node_output(ksampler_select_type.execute(sampler_name))
264
+
265
+
266
+ def sample(
267
+ model: Any,
268
+ positive: Any,
269
+ negative: Any,
270
+ latent: Any,
271
+ steps: Any,
272
+ cfg: Any,
273
+ sampler_name: str,
274
+ scheduler: str,
275
+ seed: int,
276
+ *,
277
+ denoise: float = 1.0,
278
+ ) -> Any:
279
+ """Run denoising through ComfyUI and return the denoised LATENT object.
280
+
281
+ The `latent` input follows ComfyUI's `common_ksampler` contract: a LATENT dict
282
+ containing `"samples"` and optional metadata keys.
283
+ """
284
+ common_ksampler = _get_common_ksampler()
285
+
286
+ return common_ksampler(
287
+ model,
288
+ seed,
289
+ steps,
290
+ cfg,
291
+ sampler_name,
292
+ scheduler,
293
+ positive,
294
+ negative,
295
+ latent,
296
+ denoise=denoise,
297
+ )[0]
298
+
299
+
300
+ def sample_advanced(
301
+ model: Any,
302
+ positive: Any,
303
+ negative: Any,
304
+ latent: Any,
305
+ steps: Any,
306
+ cfg: Any,
307
+ sampler_name: str,
308
+ scheduler: str,
309
+ noise_seed: int,
310
+ *,
311
+ add_noise: bool = True,
312
+ return_with_leftover_noise: bool = False,
313
+ denoise: float = 1.0,
314
+ start_at_step: int = 0,
315
+ end_at_step: int = 10000,
316
+ ) -> Any:
317
+ """Run advanced denoising with explicit noise and final-step control.
318
+
319
+ Mirrors ComfyUI `KSamplerAdvanced` semantics by mapping:
320
+ - `add_noise=False` -> `disable_noise=True`
321
+ - `return_with_leftover_noise=True` -> `force_full_denoise=False`
322
+ """
323
+ common_ksampler = _get_common_ksampler()
324
+
325
+ return common_ksampler(
326
+ model,
327
+ noise_seed,
328
+ steps,
329
+ cfg,
330
+ sampler_name,
331
+ scheduler,
332
+ positive,
333
+ negative,
334
+ latent,
335
+ denoise=denoise,
336
+ disable_noise=not add_noise,
337
+ start_step=start_at_step,
338
+ last_step=end_at_step,
339
+ force_full_denoise=not return_with_leftover_noise,
340
+ )[0]
341
+
342
+
343
+ def sample_custom(
344
+ noise: Any,
345
+ guider: Any,
346
+ sampler: Any,
347
+ sigmas: Any,
348
+ latent_image: Any,
349
+ ) -> tuple[Any, Any]:
350
+ """Run custom sampling with explicit noise/guider/sampler/sigmas inputs.
351
+
352
+ The `model` is not a direct argument here: it is already embedded in the
353
+ provided `guider` object (for example from `basic_guider()` or `cfg_guider()`).
354
+ """
355
+ sampler_custom_advanced_type = _get_sampler_custom_advanced_type()
356
+ output = sampler_custom_advanced_type.execute(
357
+ noise,
358
+ guider,
359
+ sampler,
360
+ sigmas,
361
+ latent_image,
362
+ )
363
+ result = getattr(output, "result", output)
364
+ return result[0], result[1]
365
+
366
+
367
+ __all__ = [
368
+ "sample",
369
+ "sample_advanced",
370
+ "sample_custom",
371
+ "basic_guider",
372
+ "cfg_guider",
373
+ "random_noise",
374
+ "disable_noise",
375
+ "basic_scheduler",
376
+ "karras_scheduler",
377
+ "ays_scheduler",
378
+ "flux2_scheduler",
379
+ "ltxv_scheduler",
380
+ "split_sigmas",
381
+ "split_sigmas_denoise",
382
+ "get_sampler",
383
+ ]