Load only the LoRAs the user picked on Klein; do not require snofs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-08-28 16:21:32 -05:00
co-authored by Cursor
parent a2f728fe2e
commit f51c3772e5
9 changed files with 192 additions and 25 deletions
+38 -1
View File
@@ -16,16 +16,52 @@ export const LORA_STRENGTH_DEFAULT = 1
export const LORA_STRENGTH_STEP = 0.05
export const LORA_STACK_MAX = 8
/** Graph system LoRA for MiniMax turbo. Not a user pick. */
export const MINIMAX_TURBO_LORA = 'minimax_h3_fl2v_turbo_8step_v1.0_comfyui_bf16.safetensors'
export function loraBasename(name: string) {
const trimmed = String(name || '').trim().replace(/\\/g, '/')
const parts = trimmed.split('/').filter(Boolean)
return parts[parts.length - 1] || trimmed
}
export function loraIdentityKey(name: string) {
return loraBasename(name).replace(/^xaigen-?/i, '').toLowerCase()
}
export function isXaigenOnlyLora(name: string) {
return /^xaigen/i.test(loraBasename(name))
}
/** Pick the real Comfy filename: exact path, then same basename ignoring `xaigen-`, then suffix/contains. */
export function resolveComfyLoraName(wanted: string, available: string[]) {
const target = String(wanted || '').trim().replace(/\\/g, '/')
if (!target) return ''
if (!available.length) return target
const targetLower = target.toLowerCase()
const exact = available.find(item => item.replace(/\\/g, '/') === target)
if (exact) return exact
const exactCi = available.find(item => item.replace(/\\/g, '/').toLowerCase() === targetLower)
if (exactCi) return exactCi
const identity = loraIdentityKey(target)
const identityHit = available.find(item => loraIdentityKey(item) === identity)
if (identityHit) return identityHit
const stem = identity.replace(/\.(safetensors|sft|ckpt|pt|bin)$/i, '')
if (!stem) return target
const containsHits = available.filter((item) => {
const base = loraBasename(item).toLowerCase()
return base.includes(stem) || loraIdentityKey(item).includes(stem)
})
if (!containsHits.length) return target
const suffix = containsHits.find((item) => {
const base = loraBasename(item).toLowerCase()
return base.endsWith(identity) || base.endsWith(stem) || loraIdentityKey(item).endsWith(identity)
})
return suffix || containsHits[0]
}
export function loraDisplayName(name: string) {
return loraBasename(name).replace(/\.(safetensors|sft|ckpt|pt|bin)$/i, '')
}
@@ -106,7 +142,7 @@ export function normalizeLoraStack(raw: unknown): LoraStackItem[] {
if (out.length >= LORA_STACK_MAX) break
const item = parseStackEntry(entry)
if (!item) continue
const key = loraKey(item.name)
const key = loraIdentityKey(item.name)
if (seen.has(key)) continue
seen.add(key)
out.push(item)
@@ -159,6 +195,7 @@ export function loraStacksEqual(a?: unknown, b?: unknown) {
))
}
/** User LoRA picker only. `xaigen-*` names are visible only on xAIGen. */
export function filterLorasForStudio(names: string[], xaigenStudio: boolean) {
const seen = new Set<string>()
const out: string[] = []