mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
feat: add "Respect Recommended Strength" feature to LoRA Randomizer
Add support for respecting recommended strength values from LoRA usage_tips when randomizing LoRA selection. Features: - New toggle setting to enable/disable recommended strength respect (default off) - Scale range slider (0-2, default 0.5-1.0) to adjust recommended values - Uses recommended strength × random(scale) when feature enabled - Fallbacks to original Model/Clip Strength range when no recommendation exists - Clip strength recommendations only apply when using Custom Range mode Backend changes: - Parse usage_tips JSON string to extract strength/clipStrength - Apply scale factor to recommended values during randomization - Pass new parameters through API route and node Frontend changes: - Update RandomizerConfig type with new properties - Add new UI section with toggle and dual-range slider - Wire up state management and event handlers - No layout shift (removed description text) Tests: - Add tests for enabled/disabled recommended strength in API routes - Add test verifying config passed to service - All existing tests pass Build: Include compiled Vue widgets
This commit is contained in:
@@ -16,6 +16,9 @@
|
||||
:last-used="state.lastUsed.value"
|
||||
:current-loras="currentLoras"
|
||||
:can-reuse-last="canReuseLast"
|
||||
:use-recommended-strength="state.useRecommendedStrength.value"
|
||||
:recommended-strength-scale-min="state.recommendedStrengthScaleMin.value"
|
||||
:recommended-strength-scale-max="state.recommendedStrengthScaleMax.value"
|
||||
@update:count-mode="state.countMode.value = $event"
|
||||
@update:count-fixed="state.countFixed.value = $event"
|
||||
@update:count-min="state.countMin.value = $event"
|
||||
@@ -26,6 +29,9 @@
|
||||
@update:clip-strength-min="state.clipStrengthMin.value = $event"
|
||||
@update:clip-strength-max="state.clipStrengthMax.value = $event"
|
||||
@update:roll-mode="state.rollMode.value = $event"
|
||||
@update:use-recommended-strength="state.useRecommendedStrength.value = $event"
|
||||
@update:recommended-strength-scale-min="state.recommendedStrengthScaleMin.value = $event"
|
||||
@update:recommended-strength-scale-max="state.recommendedStrengthScaleMax.value = $event"
|
||||
@generate-fixed="handleGenerateFixed"
|
||||
@always-randomize="handleAlwaysRandomize"
|
||||
@reuse-last="handleReuseLast"
|
||||
|
||||
@@ -73,6 +73,40 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recommended Strength -->
|
||||
<div class="setting-section">
|
||||
<div class="section-header-with-toggle">
|
||||
<label class="setting-label">
|
||||
Respect Recommended Strength
|
||||
</label>
|
||||
<button
|
||||
type="button"
|
||||
class="toggle-switch"
|
||||
:class="{ 'toggle-switch--active': useRecommendedStrength }"
|
||||
@click="$emit('update:useRecommendedStrength', !useRecommendedStrength)"
|
||||
role="switch"
|
||||
:aria-checked="useRecommendedStrength"
|
||||
title="Use recommended strength values from usage tips"
|
||||
>
|
||||
<span class="toggle-switch__track"></span>
|
||||
<span class="toggle-switch__thumb"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="slider-container" :class="{ 'slider-container--disabled': !useRecommendedStrength }">
|
||||
<DualRangeSlider
|
||||
:min="0"
|
||||
:max="2"
|
||||
:value-min="recommendedStrengthScaleMin"
|
||||
:value-max="recommendedStrengthScaleMax"
|
||||
:step="0.1"
|
||||
:default-range="{ min: 0.5, max: 1.0 }"
|
||||
:disabled="!useRecommendedStrength"
|
||||
@update:value-min="$emit('update:recommendedStrengthScaleMin', $event)"
|
||||
@update:value-max="$emit('update:recommendedStrengthScaleMax', $event)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Clip Strength Range -->
|
||||
<div class="setting-section">
|
||||
<div class="section-header-with-toggle">
|
||||
@@ -200,6 +234,9 @@ defineProps<{
|
||||
lastUsed: LoraEntry[] | null
|
||||
currentLoras: LoraEntry[]
|
||||
canReuseLast: boolean
|
||||
useRecommendedStrength: boolean
|
||||
recommendedStrengthScaleMin: number
|
||||
recommendedStrengthScaleMax: number
|
||||
}>()
|
||||
|
||||
defineEmits<{
|
||||
@@ -213,6 +250,9 @@ defineEmits<{
|
||||
'update:clipStrengthMin': [value: number]
|
||||
'update:clipStrengthMax': [value: number]
|
||||
'update:rollMode': [value: 'fixed' | 'always']
|
||||
'update:useRecommendedStrength': [value: boolean]
|
||||
'update:recommendedStrengthScaleMin': [value: number]
|
||||
'update:recommendedStrengthScaleMax': [value: number]
|
||||
'generate-fixed': []
|
||||
'always-randomize': []
|
||||
'reuse-last': []
|
||||
@@ -341,6 +381,11 @@ const areLorasEqual = (a: LoraEntry[] | null, b: LoraEntry[] | null): boolean =>
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.slider-container--disabled {
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Toggle Switch (same style as LicenseSection) */
|
||||
.toggle-switch {
|
||||
position: relative;
|
||||
|
||||
@@ -66,6 +66,9 @@ export interface RandomizerConfig {
|
||||
clip_strength_max: number
|
||||
roll_mode: 'fixed' | 'always'
|
||||
last_used?: LoraEntry[] | null
|
||||
use_recommended_strength: boolean
|
||||
recommended_strength_scale_min: number
|
||||
recommended_strength_scale_max: number
|
||||
}
|
||||
|
||||
export interface LoraEntry {
|
||||
|
||||
@@ -14,6 +14,9 @@ export function useLoraRandomizerState(widget: ComponentWidget) {
|
||||
const clipStrengthMax = ref(1.0)
|
||||
const rollMode = ref<'fixed' | 'always'>('fixed')
|
||||
const isRolling = ref(false)
|
||||
const useRecommendedStrength = ref(false)
|
||||
const recommendedStrengthScaleMin = ref(0.5)
|
||||
const recommendedStrengthScaleMax = ref(1.0)
|
||||
|
||||
// Track last used combination (for backend roll mode)
|
||||
const lastUsed = ref<LoraEntry[] | null>(null)
|
||||
@@ -31,6 +34,9 @@ export function useLoraRandomizerState(widget: ComponentWidget) {
|
||||
clip_strength_max: clipStrengthMax.value,
|
||||
roll_mode: rollMode.value,
|
||||
last_used: lastUsed.value,
|
||||
use_recommended_strength: useRecommendedStrength.value,
|
||||
recommended_strength_scale_min: recommendedStrengthScaleMin.value,
|
||||
recommended_strength_scale_max: recommendedStrengthScaleMax.value,
|
||||
})
|
||||
|
||||
// Restore state from config object
|
||||
@@ -56,6 +62,9 @@ export function useLoraRandomizerState(widget: ComponentWidget) {
|
||||
rollMode.value = 'fixed'
|
||||
}
|
||||
lastUsed.value = config.last_used || null
|
||||
useRecommendedStrength.value = config.use_recommended_strength ?? false
|
||||
recommendedStrengthScaleMin.value = config.recommended_strength_scale_min ?? 0.5
|
||||
recommendedStrengthScaleMax.value = config.recommended_strength_scale_max ?? 1.0
|
||||
}
|
||||
|
||||
// Roll loras - call API to get random selection
|
||||
@@ -76,6 +85,9 @@ export function useLoraRandomizerState(widget: ComponentWidget) {
|
||||
clip_strength_min: config.clip_strength_min,
|
||||
clip_strength_max: config.clip_strength_max,
|
||||
locked_loras: lockedLoras,
|
||||
use_recommended_strength: config.use_recommended_strength,
|
||||
recommended_strength_scale_min: config.recommended_strength_scale_min,
|
||||
recommended_strength_scale_max: config.recommended_strength_scale_max,
|
||||
}
|
||||
|
||||
// Add count parameters
|
||||
@@ -130,6 +142,7 @@ export function useLoraRandomizerState(widget: ComponentWidget) {
|
||||
|
||||
// Computed properties
|
||||
const isClipStrengthDisabled = computed(() => useSameClipStrength.value)
|
||||
const isRecommendedStrengthEnabled = computed(() => useRecommendedStrength.value)
|
||||
|
||||
// Watch all state changes and update widget value
|
||||
watch([
|
||||
@@ -143,6 +156,9 @@ export function useLoraRandomizerState(widget: ComponentWidget) {
|
||||
clipStrengthMin,
|
||||
clipStrengthMax,
|
||||
rollMode,
|
||||
useRecommendedStrength,
|
||||
recommendedStrengthScaleMin,
|
||||
recommendedStrengthScaleMax,
|
||||
], () => {
|
||||
const config = buildConfig()
|
||||
if (widget.updateConfig) {
|
||||
@@ -166,9 +182,13 @@ export function useLoraRandomizerState(widget: ComponentWidget) {
|
||||
rollMode,
|
||||
isRolling,
|
||||
lastUsed,
|
||||
useRecommendedStrength,
|
||||
recommendedStrengthScaleMin,
|
||||
recommendedStrengthScaleMax,
|
||||
|
||||
// Computed
|
||||
isClipStrengthDisabled,
|
||||
isRecommendedStrengthEnabled,
|
||||
|
||||
// Methods
|
||||
buildConfig,
|
||||
|
||||
@@ -7,7 +7,7 @@ import type { LoraPoolConfig, LegacyLoraPoolConfig, RandomizerConfig } from './c
|
||||
const LORA_POOL_WIDGET_MIN_WIDTH = 500
|
||||
const LORA_POOL_WIDGET_MIN_HEIGHT = 400
|
||||
const LORA_RANDOMIZER_WIDGET_MIN_WIDTH = 500
|
||||
const LORA_RANDOMIZER_WIDGET_MIN_HEIGHT = 430
|
||||
const LORA_RANDOMIZER_WIDGET_MIN_HEIGHT = 510
|
||||
const LORA_RANDOMIZER_WIDGET_MAX_HEIGHT = LORA_RANDOMIZER_WIDGET_MIN_HEIGHT
|
||||
|
||||
// @ts-ignore - ComfyUI external module
|
||||
|
||||
Reference in New Issue
Block a user