- model_kind: Anima LLLite, Qwen-Image block-wise and Z-Image Fun ControlNets (and other ModelPatchLoader files) go to model_patches, not controlnet; import and Tidy follow. - api/mcp_model_use.py: search_models / get_model say which node types load each model, or where a misfiled one belongs; move_model moves it there behind a new "files" gate (asks by default, never overwrites). - An empty drop-down in add_node says ComfyUI found no file; the task tab switch is no longer logged as the user's canvas change. - The folded task list stays while the pointer is in the box around its button and the list. - The message box's picture button picks gallery pictures; "@" offers the gallery's newest and searches it as you type. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
45 lines
2.1 KiB
JavaScript
45 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 (nodeType === 'modelpatchloader') return ['model_patches'];
|
|
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));
|
|
}
|