feat: add "Strength Range" option to LoRA preset parameters dropdown, fixes #386

This commit is contained in:
Will Miao
2026-01-08 22:19:19 +08:00
parent f62b3f62be
commit f2e12c0fd3
11 changed files with 66 additions and 25 deletions

View File

@@ -918,11 +918,13 @@
"addPresetParameter": "Voreingestellten Parameter hinzufügen...", "addPresetParameter": "Voreingestellten Parameter hinzufügen...",
"strengthMin": "Stärke Min", "strengthMin": "Stärke Min",
"strengthMax": "Stärke Max", "strengthMax": "Stärke Max",
"strengthRange": "Stärkenbereich",
"strength": "Stärke", "strength": "Stärke",
"clipStrength": "Clip-Stärke", "clipStrength": "Clip-Stärke",
"clipSkip": "Clip Skip", "clipSkip": "Clip Skip",
"valuePlaceholder": "Wert", "valuePlaceholder": "Wert",
"add": "Hinzufügen" "add": "Hinzufügen",
"invalidRange": "Ungültiges Bereichsformat. Verwenden Sie x.x-y.y"
}, },
"triggerWords": { "triggerWords": {
"label": "Trigger Words", "label": "Trigger Words",

View File

@@ -918,11 +918,13 @@
"addPresetParameter": "Add preset parameter...", "addPresetParameter": "Add preset parameter...",
"strengthMin": "Strength Min", "strengthMin": "Strength Min",
"strengthMax": "Strength Max", "strengthMax": "Strength Max",
"strengthRange": "Strength Range",
"strength": "Strength", "strength": "Strength",
"clipStrength": "Clip Strength", "clipStrength": "Clip Strength",
"clipSkip": "Clip Skip", "clipSkip": "Clip Skip",
"valuePlaceholder": "Value", "valuePlaceholder": "Value",
"add": "Add" "add": "Add",
"invalidRange": "Invalid range format. Use x.x-y.y"
}, },
"triggerWords": { "triggerWords": {
"label": "Trigger Words", "label": "Trigger Words",

View File

@@ -918,11 +918,13 @@
"addPresetParameter": "Añadir parámetro preestablecido...", "addPresetParameter": "Añadir parámetro preestablecido...",
"strengthMin": "Fuerza mínima", "strengthMin": "Fuerza mínima",
"strengthMax": "Fuerza máxima", "strengthMax": "Fuerza máxima",
"strengthRange": "Rango de fuerza",
"strength": "Fuerza", "strength": "Fuerza",
"clipStrength": "Fuerza de Clip", "clipStrength": "Fuerza de Clip",
"clipSkip": "Clip Skip", "clipSkip": "Clip Skip",
"valuePlaceholder": "Valor", "valuePlaceholder": "Valor",
"add": "Añadir" "add": "Añadir",
"invalidRange": "Formato de rango inválido. Use x.x-y.y"
}, },
"triggerWords": { "triggerWords": {
"label": "Palabras clave", "label": "Palabras clave",

View File

@@ -918,11 +918,13 @@
"addPresetParameter": "Ajouter un paramètre prédéfini...", "addPresetParameter": "Ajouter un paramètre prédéfini...",
"strengthMin": "Force Min", "strengthMin": "Force Min",
"strengthMax": "Force Max", "strengthMax": "Force Max",
"strengthRange": "Gamme de force",
"strength": "Force", "strength": "Force",
"clipStrength": "Force Clip", "clipStrength": "Force Clip",
"clipSkip": "Clip Skip", "clipSkip": "Clip Skip",
"valuePlaceholder": "Valeur", "valuePlaceholder": "Valeur",
"add": "Ajouter" "add": "Ajouter",
"invalidRange": "Format de plage invalide. Utilisez x.x-y.y"
}, },
"triggerWords": { "triggerWords": {
"label": "Mots-clés", "label": "Mots-clés",

View File

@@ -918,11 +918,13 @@
"addPresetParameter": "הוסף פרמטר קבוע מראש...", "addPresetParameter": "הוסף פרמטר קבוע מראש...",
"strengthMin": "חוזק מינימלי", "strengthMin": "חוזק מינימלי",
"strengthMax": "חוזק מקסימלי", "strengthMax": "חוזק מקסימלי",
"strengthRange": "טווח עוצמה",
"strength": "חוזק", "strength": "חוזק",
"clipStrength": "עוצמת CLIP", "clipStrength": "עוצמת CLIP",
"clipSkip": "Clip Skip", "clipSkip": "Clip Skip",
"valuePlaceholder": "ערך", "valuePlaceholder": "ערך",
"add": "הוסף" "add": "הוסף",
"invalidRange": "פורמט טווח לא תקין. השתמש ב-x.x-y.y"
}, },
"triggerWords": { "triggerWords": {
"label": "מילות טריגר", "label": "מילות טריגר",

View File

@@ -918,11 +918,13 @@
"addPresetParameter": "プリセットパラメータを追加...", "addPresetParameter": "プリセットパラメータを追加...",
"strengthMin": "強度最小", "strengthMin": "強度最小",
"strengthMax": "強度最大", "strengthMax": "強度最大",
"strengthRange": "強度範囲",
"strength": "強度", "strength": "強度",
"clipStrength": "クリップ強度", "clipStrength": "クリップ強度",
"clipSkip": "Clip Skip", "clipSkip": "Clip Skip",
"valuePlaceholder": "値", "valuePlaceholder": "値",
"add": "追加" "add": "追加",
"invalidRange": "無効な範囲形式です。x.x-y.y を使用してください"
}, },
"triggerWords": { "triggerWords": {
"label": "トリガーワード", "label": "トリガーワード",

View File

@@ -918,11 +918,13 @@
"addPresetParameter": "프리셋 매개변수 추가...", "addPresetParameter": "프리셋 매개변수 추가...",
"strengthMin": "최소 강도", "strengthMin": "최소 강도",
"strengthMax": "최대 강도", "strengthMax": "최대 강도",
"strengthRange": "강도 범위",
"strength": "강도", "strength": "강도",
"clipStrength": "클립 강도", "clipStrength": "클립 강도",
"clipSkip": "클립 스킵", "clipSkip": "클립 스킵",
"valuePlaceholder": "값", "valuePlaceholder": "값",
"add": "추가" "add": "추가",
"invalidRange": "잘못된 범위 형식입니다. x.x-y.y를 사용하세요"
}, },
"triggerWords": { "triggerWords": {
"label": "트리거 단어", "label": "트리거 단어",

View File

@@ -918,11 +918,13 @@
"addPresetParameter": "Добавить предустановленный параметр...", "addPresetParameter": "Добавить предустановленный параметр...",
"strengthMin": "Мин. сила", "strengthMin": "Мин. сила",
"strengthMax": "Макс. сила", "strengthMax": "Макс. сила",
"strengthRange": "Диапазон силы",
"strength": "Сила", "strength": "Сила",
"clipStrength": "Сила клипа", "clipStrength": "Сила клипа",
"clipSkip": "Clip Skip", "clipSkip": "Clip Skip",
"valuePlaceholder": "Значение", "valuePlaceholder": "Значение",
"add": "Добавить" "add": "Добавить",
"invalidRange": "Неверный формат диапазона. Используйте x.x-y.y"
}, },
"triggerWords": { "triggerWords": {
"label": "Триггерные слова", "label": "Триггерные слова",

View File

@@ -918,11 +918,13 @@
"addPresetParameter": "添加预设参数...", "addPresetParameter": "添加预设参数...",
"strengthMin": "最小强度", "strengthMin": "最小强度",
"strengthMax": "最大强度", "strengthMax": "最大强度",
"strengthRange": "强度范围",
"strength": "强度", "strength": "强度",
"clipStrength": "Clip 强度", "clipStrength": "Clip 强度",
"clipSkip": "Clip Skip", "clipSkip": "Clip Skip",
"valuePlaceholder": "数值", "valuePlaceholder": "数值",
"add": "添加" "add": "添加",
"invalidRange": "无效的范围格式。请使用 x.x-y.y"
}, },
"triggerWords": { "triggerWords": {
"label": "触发词", "label": "触发词",

View File

@@ -918,11 +918,13 @@
"addPresetParameter": "新增預設參數...", "addPresetParameter": "新增預設參數...",
"strengthMin": "最小強度", "strengthMin": "最小強度",
"strengthMax": "最大強度", "strengthMax": "最大強度",
"strengthRange": "強度範圍",
"strength": "強度", "strength": "強度",
"clipStrength": "Clip 強度", "clipStrength": "Clip 強度",
"clipSkip": "Clip Skip", "clipSkip": "Clip Skip",
"valuePlaceholder": "數值", "valuePlaceholder": "數值",
"add": "新增" "add": "新增",
"invalidRange": "無效的範圍格式。請使用 x.x-y.y"
}, },
"triggerWords": { "triggerWords": {
"label": "觸發詞", "label": "觸發詞",

View File

@@ -672,6 +672,7 @@ function renderLoraSpecificContent(lora, escapedWords) {
<option value="">${translate('modals.model.usageTips.addPresetParameter', {}, 'Add preset parameter...')}</option> <option value="">${translate('modals.model.usageTips.addPresetParameter', {}, 'Add preset parameter...')}</option>
<option value="strength_min">${translate('modals.model.usageTips.strengthMin', {}, 'Strength Min')}</option> <option value="strength_min">${translate('modals.model.usageTips.strengthMin', {}, 'Strength Min')}</option>
<option value="strength_max">${translate('modals.model.usageTips.strengthMax', {}, 'Strength Max')}</option> <option value="strength_max">${translate('modals.model.usageTips.strengthMax', {}, 'Strength Max')}</option>
<option value="strength_range">${translate('modals.model.usageTips.strengthRange', {}, 'Strength Range')}</option>
<option value="strength">${translate('modals.model.usageTips.strength', {}, 'Strength')}</option> <option value="strength">${translate('modals.model.usageTips.strength', {}, 'Strength')}</option>
<option value="clip_strength">${translate('modals.model.usageTips.clipStrength', {}, 'Clip Strength')}</option> <option value="clip_strength">${translate('modals.model.usageTips.clipStrength', {}, 'Clip Strength')}</option>
<option value="clip_skip">${translate('modals.model.usageTips.clipSkip', {}, 'Clip Skip')}</option> <option value="clip_skip">${translate('modals.model.usageTips.clipSkip', {}, 'Clip Skip')}</option>
@@ -814,12 +815,21 @@ function setupLoraSpecificFields(filePath) {
const selected = this.value; const selected = this.value;
if (selected) { if (selected) {
presetValue.style.display = 'inline-block'; presetValue.style.display = 'inline-block';
presetValue.min = selected.includes('strength') ? -10 : 0; if (selected === 'strength_range') {
presetValue.max = selected.includes('strength') ? 10 : 10; presetValue.type = 'text';
presetValue.step = 0.5; presetValue.placeholder = 'e.g. 0.8-1.2';
if (selected === 'clip_skip') { presetValue.removeAttribute('min');
presetValue.removeAttribute('max');
presetValue.removeAttribute('step');
} else {
presetValue.type = 'number'; presetValue.type = 'number';
presetValue.step = 1; presetValue.placeholder = translate('modals.model.usageTips.valuePlaceholder', {}, 'Value');
presetValue.min = selected.includes('strength') ? -10 : 0;
presetValue.max = selected.includes('strength') ? 10 : 10;
presetValue.step = 0.5;
if (selected === 'clip_skip') {
presetValue.step = 1;
}
} }
// Add auto-focus // Add auto-focus
setTimeout(() => presetValue.focus(), 0); setTimeout(() => presetValue.focus(), 0);
@@ -840,7 +850,18 @@ function setupLoraSpecificFields(filePath) {
document.querySelector(`.model-card[data-filepath="${filePath}"]`); document.querySelector(`.model-card[data-filepath="${filePath}"]`);
const currentPresets = parsePresets(loraCard?.dataset.usage_tips); const currentPresets = parsePresets(loraCard?.dataset.usage_tips);
currentPresets[key] = parseFloat(value); if (key === 'strength_range') {
const rangeMatch = value.match(/^(-?\d*\.?\d+)\s*[-~]\s*(-?\d*\.?\d+)$/);
if (rangeMatch) {
currentPresets['strength_min'] = parseFloat(rangeMatch[1]);
currentPresets['strength_max'] = parseFloat(rangeMatch[2]);
} else {
showToast('modals.model.usageTips.invalidRange', {}, 'error', 'Invalid range format. Use x.x-y.y');
return;
}
} else {
currentPresets[key] = parseFloat(value);
}
const newPresetsJson = JSON.stringify(currentPresets); const newPresetsJson = JSON.stringify(currentPresets);
await getModelApiClient().saveModelMetadata(currentPath, { usage_tips: newPresetsJson }); await getModelApiClient().saveModelMetadata(currentPath, { usage_tips: newPresetsJson });