Files
DemonGatanjieu-Anomalous_Mo…/web/modules/model_policies.js
T
DemonGatanjieuandClaude Opus 5.5 4cfff5382e Make Model Check offer same-name files as candidates, not as the same file
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>
2026-10-03 14:23:05 +08:00

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));
}