For a workflow without fingerprints, a missing ordinary model took the local same-name file's hash as its evidence, so it showed as "the same file under another name" and counted among those put in at once. Only the workflow's own record is evidence now; the one same-name file the node can load is a candidate, and a size candidate with the same name is shown as likely, first. Foundation components still go by fingerprint only. Model Check also reads GGUF values and resolves upscale models. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
44 lines
2.1 KiB
JavaScript
44 lines
2.1 KiB
JavaScript
const PHYSICAL_RENAME_PROTECTED_TYPES = new Set([
|
|
'vae',
|
|
'vae_approx',
|
|
'clip',
|
|
'text_encoders',
|
|
'clip_vision',
|
|
]);
|
|
|
|
// Scanner coverage is separate. These categories may be scanned, but automatic
|
|
// Model Check redirection requires workflow-carried cryptographic identity.
|
|
const HASH_ONLY_RECOVERY_TYPES = new Set([
|
|
'vae',
|
|
'vae_approx',
|
|
'clip',
|
|
'text_encoders',
|
|
'clip_vision',
|
|
]);
|
|
|
|
export function isPhysicalRenameProtectedType(folderType) {
|
|
return PHYSICAL_RENAME_PROTECTED_TYPES.has(String(folderType || '').trim().toLowerCase());
|
|
}
|
|
|
|
export function inferModelFolderTypes(node, widget) {
|
|
const widgetName = String(widget?.name || '').toLowerCase();
|
|
const nodeType = String(node?.type || '').toLowerCase();
|
|
const key = `${widgetName} ${nodeType}`;
|
|
|
|
if (key.includes('clip_vision') || key.includes('clip vision') || nodeType.includes('clipvision')) return ['clip_vision'];
|
|
if (key.includes('vae_approx') || key.includes('vae approx')) return ['vae_approx'];
|
|
if (widgetName.includes('vae') || nodeType === 'vaeloader' || key.includes('vae loader')) return ['vae'];
|
|
if (widgetName.includes('lora') || key.includes('lora')) return ['loras'];
|
|
if (widgetName.includes('control_net') || widgetName.includes('controlnet') || key.includes('controlnet')) return ['controlnet'];
|
|
if (widgetName.includes('ckpt') || widgetName.includes('checkpoint') || key.includes('checkpoint')) return ['checkpoints'];
|
|
if (widgetName.includes('unet') || widgetName.includes('diffusion_model') || key.includes('unet loader')) return ['diffusion_models', 'unet'];
|
|
if (widgetName.includes('clip_name') || widgetName.includes('text_encoder') || nodeType.includes('cliploader')) return ['clip', 'text_encoders'];
|
|
if (nodeType.includes('upscalemodel') || widgetName.includes('upscale_model')) return ['upscale_models'];
|
|
return [];
|
|
}
|
|
|
|
export function requiresHashForModelRecovery(node, widget) {
|
|
const types = inferModelFolderTypes(node, widget);
|
|
return types.length > 0 && types.every(type => HASH_ONLY_RECOVERY_TYPES.has(type));
|
|
}
|