refactor(frontend): extract base model aliases
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
toResolverContextModel,
|
||||
} from '../web/resolver/node_context_menu.js';
|
||||
import { startSplitterDrag } from '../web/resolver/utils/splitter_drag.js';
|
||||
import { baseModelAliasMethods } from '../web/resolver/search/base_model_alias_methods.js';
|
||||
import {
|
||||
getCustomNodeModelAdapter,
|
||||
getCustomNodeModelCategory,
|
||||
@@ -3007,10 +3008,12 @@ test('native Xet progress bar uses live network bytes against the known final fi
|
||||
});
|
||||
|
||||
test('base model alias resolves FLUX KREA as Flux.1 Krea', () => {
|
||||
const normalizeBaseModelToken = eval(`(${extractMethod(searchPanelMethodsSource, 'normalizeBaseModelToken')})`);
|
||||
const getBaseModelTokenVariants = eval(`(${extractMethod(searchPanelMethodsSource, 'getBaseModelTokenVariants')})`);
|
||||
const resolveBaseModelAliasExact = eval(`(${extractMethod(searchPanelMethodsSource, 'resolveBaseModelAliasExact')})`);
|
||||
const resolveBaseModelAlias = eval(`(${extractMethod(searchPanelMethodsSource, 'resolveBaseModelAlias')})`);
|
||||
const {
|
||||
normalizeBaseModelToken,
|
||||
getBaseModelTokenVariants,
|
||||
resolveBaseModelAliasExact,
|
||||
resolveBaseModelAlias,
|
||||
} = baseModelAliasMethods;
|
||||
const dialog = {
|
||||
baseModels: {
|
||||
base_models: [
|
||||
@@ -3126,10 +3129,12 @@ test('auto base model keeps workflow path context when a delayed search result d
|
||||
});
|
||||
|
||||
test('base model path mapping ignores conflicting full-path base model', () => {
|
||||
const normalizeBaseModelToken = eval(`(${extractMethod(searchPanelMethodsSource, 'normalizeBaseModelToken')})`);
|
||||
const getBaseModelTokenVariants = eval(`(${extractMethod(searchPanelMethodsSource, 'getBaseModelTokenVariants')})`);
|
||||
const resolveBaseModelAliasExact = eval(`(${extractMethod(searchPanelMethodsSource, 'resolveBaseModelAliasExact')})`);
|
||||
const resolveBaseModelAlias = eval(`(${extractMethod(searchPanelMethodsSource, 'resolveBaseModelAlias')})`);
|
||||
const {
|
||||
normalizeBaseModelToken,
|
||||
getBaseModelTokenVariants,
|
||||
resolveBaseModelAliasExact,
|
||||
resolveBaseModelAlias,
|
||||
} = baseModelAliasMethods;
|
||||
const isBaseModelPathMappingCompatible = eval(`(${extractMethod(downloadTargetMethodsSource, 'isBaseModelPathMappingCompatible')})`);
|
||||
const resolveBaseModelPathMapping = eval(`(${extractMethod(downloadTargetMethodsSource, 'resolveBaseModelPathMapping')})`);
|
||||
const dialog = {
|
||||
|
||||
@@ -13,6 +13,7 @@ import { tabsLoadedMethods } from "./views/tabs_loaded_methods.js";
|
||||
import { downloadTargetMethods } from "./search/download_target_methods.js";
|
||||
import { searchPanelMethods } from "./search/search_panel.js";
|
||||
import { searchSourceMethods } from "./search/search_source_methods.js";
|
||||
import { baseModelAliasMethods } from "./search/base_model_alias_methods.js";
|
||||
import { queueMethods } from "./actions/queue_methods.js";
|
||||
import { queueStorageMethods } from "./actions/queue_storage_methods.js";
|
||||
import { downloadProgressMethods } from "./actions/download_progress_methods.js";
|
||||
@@ -335,6 +336,7 @@ function applyDialogMethods(...sources) {
|
||||
|
||||
applyDialogMethods(
|
||||
searchSourceMethods,
|
||||
baseModelAliasMethods,
|
||||
searchPanelMethods,
|
||||
modelInfoMethods,
|
||||
renderFormatMethods,
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
export const baseModelAliasMethods = {
|
||||
getBaseModelAliases() {
|
||||
const baseModelsList = this.baseModels?.base_models;
|
||||
if (Array.isArray(baseModelsList) && baseModelsList.length > 0) {
|
||||
return baseModelsList.map(m => ({ value: m.name, aliases: m.aliases || [] }));
|
||||
}
|
||||
// Fallback to hardcoded list
|
||||
return [
|
||||
{ value: 'Z-Image', aliases: ['zimage', 'z image', 'z-image', 'z_image', 'zImageTurbo', 'z image turbo'] },
|
||||
{ value: 'Pony', aliases: ['pony', 'ponyxl', 'pony diffusion', 'pony realism'] },
|
||||
{ value: 'Illustrious', aliases: ['illustrious', 'illustriousxl', 'illustrious xl'] },
|
||||
{ value: 'SDXL 1.0', aliases: ['sdxl', 'sdxl10', 'sdxl 1.0', 'stable diffusion xl'] },
|
||||
{ value: 'SD 1.5', aliases: ['sd15', 'sd 1.5', 'sd1.5', 'stable diffusion 1.5'] },
|
||||
{ value: 'Flux.1 D', aliases: ['flux', 'flux1', 'flux.1', 'flux dev', 'flux.1 d', 'flux1d'] },
|
||||
{ value: 'Flux.1 S', aliases: ['flux schnell', 'flux.1 s', 'flux1s'] },
|
||||
{ value: 'Qwen Image', aliases: ['qwen image', 'qwenimage', 'qwen-image'] },
|
||||
{ value: 'Hunyuan 1', aliases: ['hunyuan', 'hunyuan1'] },
|
||||
{ value: 'WAN Video', aliases: ['wan', 'wan video', 'wanvideo'] },
|
||||
{ value: 'NoobAI', aliases: ['noobai', 'noob ai'] },
|
||||
{ value: 'HiDream', aliases: ['hidream', 'hi dream'] }
|
||||
];
|
||||
},
|
||||
|
||||
normalizeBaseModelToken(value = '') {
|
||||
return String(value || '')
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '');
|
||||
},
|
||||
|
||||
getBaseModelTokenVariants(value = '') {
|
||||
const text = String(value || '').trim();
|
||||
if (!text) return new Set();
|
||||
const variants = [
|
||||
text,
|
||||
text.replace(/(\d+)(?:[\s._-]+0)+(?!\d)/g, '$1')
|
||||
];
|
||||
const normalized = this.normalizeBaseModelToken(text);
|
||||
if (normalized.startsWith('flux1') && normalized.length > 'flux1'.length) {
|
||||
variants.push(`flux${normalized.slice('flux1'.length)}`);
|
||||
}
|
||||
return new Set(
|
||||
variants
|
||||
.map(item => this.normalizeBaseModelToken(item))
|
||||
.filter(Boolean)
|
||||
);
|
||||
},
|
||||
|
||||
resolveBaseModelAliasExact(value = '') {
|
||||
const tokens = this.getBaseModelTokenVariants(value);
|
||||
if (!tokens.size) return '';
|
||||
for (const entry of this.getBaseModelAliases()) {
|
||||
const aliases = [entry.value, ...(entry.aliases || [])];
|
||||
if (aliases.some(alias => {
|
||||
const aliasTokens = this.getBaseModelTokenVariants(alias);
|
||||
return [...aliasTokens].some(aliasToken => tokens.has(aliasToken));
|
||||
})) {
|
||||
return entry.value;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
resolveBaseModelAlias(value = '') {
|
||||
const tokens = this.getBaseModelTokenVariants(value);
|
||||
if (!tokens.size) return '';
|
||||
const exact = this.resolveBaseModelAliasExact(value);
|
||||
if (exact) return exact;
|
||||
|
||||
for (const entry of this.getBaseModelAliases()) {
|
||||
const aliases = [entry.value, ...(entry.aliases || [])];
|
||||
if (aliases.some(alias => {
|
||||
const aliasTokens = this.getBaseModelTokenVariants(alias);
|
||||
return [...aliasTokens].some(aliasToken => (
|
||||
aliasToken && [...tokens].some(token => (
|
||||
aliasToken.includes(token) || token.includes(aliasToken)
|
||||
))
|
||||
));
|
||||
})) {
|
||||
return entry.value;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
resolveBaseModelAliasFromPath(path = '') {
|
||||
const text = String(path || '').trim();
|
||||
if (!text) return '';
|
||||
|
||||
const parts = text
|
||||
.split(/[\\/]+/)
|
||||
.map(part => part.trim())
|
||||
.filter(Boolean);
|
||||
const directoryParts = parts.filter(part => !this.hasModelExtension(part));
|
||||
|
||||
for (const part of directoryParts) {
|
||||
const exact = this.resolveBaseModelAliasExact(part);
|
||||
if (exact) return exact;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
};
|
||||
@@ -88,85 +88,6 @@ export const searchPanelMethods = {
|
||||
];
|
||||
},
|
||||
|
||||
normalizeBaseModelToken(value = '') {
|
||||
return String(value || '')
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, '');
|
||||
},
|
||||
|
||||
getBaseModelTokenVariants(value = '') {
|
||||
const text = String(value || '').trim();
|
||||
if (!text) return new Set();
|
||||
const variants = [
|
||||
text,
|
||||
text.replace(/(\d+)(?:[\s._-]+0)+(?!\d)/g, '$1')
|
||||
];
|
||||
const normalized = this.normalizeBaseModelToken(text);
|
||||
if (normalized.startsWith('flux1') && normalized.length > 'flux1'.length) {
|
||||
variants.push(`flux${normalized.slice('flux1'.length)}`);
|
||||
}
|
||||
return new Set(
|
||||
variants
|
||||
.map(item => this.normalizeBaseModelToken(item))
|
||||
.filter(Boolean)
|
||||
);
|
||||
},
|
||||
|
||||
resolveBaseModelAliasExact(value = '') {
|
||||
const tokens = this.getBaseModelTokenVariants(value);
|
||||
if (!tokens.size) return '';
|
||||
for (const entry of this.getBaseModelAliases()) {
|
||||
const aliases = [entry.value, ...(entry.aliases || [])];
|
||||
if (aliases.some(alias => {
|
||||
const aliasTokens = this.getBaseModelTokenVariants(alias);
|
||||
return [...aliasTokens].some(aliasToken => tokens.has(aliasToken));
|
||||
})) {
|
||||
return entry.value;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
resolveBaseModelAlias(value = '') {
|
||||
const tokens = this.getBaseModelTokenVariants(value);
|
||||
if (!tokens.size) return '';
|
||||
const exact = this.resolveBaseModelAliasExact(value);
|
||||
if (exact) return exact;
|
||||
|
||||
for (const entry of this.getBaseModelAliases()) {
|
||||
const aliases = [entry.value, ...(entry.aliases || [])];
|
||||
if (aliases.some(alias => {
|
||||
const aliasTokens = this.getBaseModelTokenVariants(alias);
|
||||
return [...aliasTokens].some(aliasToken => (
|
||||
aliasToken && [...tokens].some(token => (
|
||||
aliasToken.includes(token) || token.includes(aliasToken)
|
||||
))
|
||||
));
|
||||
})) {
|
||||
return entry.value;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
resolveBaseModelAliasFromPath(path = '') {
|
||||
const text = String(path || '').trim();
|
||||
if (!text) return '';
|
||||
|
||||
const parts = text
|
||||
.split(/[\\/]+/)
|
||||
.map(part => part.trim())
|
||||
.filter(Boolean);
|
||||
const directoryParts = parts.filter(part => !this.hasModelExtension(part));
|
||||
|
||||
for (const part of directoryParts) {
|
||||
const exact = this.resolveBaseModelAliasExact(part);
|
||||
if (exact) return exact;
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
getMissingLocalBaseModel(missing = {}, minConfidence = 70) {
|
||||
const bestMatch = this.getBestLocalMatch?.(missing, minConfidence);
|
||||
const matchModel = bestMatch?.model || {};
|
||||
@@ -367,28 +288,6 @@ export const searchPanelMethods = {
|
||||
return this.getMissingAutoBaseModelInfo(missing).message;
|
||||
},
|
||||
|
||||
getBaseModelAliases() {
|
||||
const baseModelsList = this.baseModels?.base_models;
|
||||
if (Array.isArray(baseModelsList) && baseModelsList.length > 0) {
|
||||
return baseModelsList.map(m => ({ value: m.name, aliases: m.aliases || [] }));
|
||||
}
|
||||
// Fallback to hardcoded list
|
||||
return [
|
||||
{ value: 'Z-Image', aliases: ['zimage', 'z image', 'z-image', 'z_image', 'zImageTurbo', 'z image turbo'] },
|
||||
{ value: 'Pony', aliases: ['pony', 'ponyxl', 'pony diffusion', 'pony realism'] },
|
||||
{ value: 'Illustrious', aliases: ['illustrious', 'illustriousxl', 'illustrious xl'] },
|
||||
{ value: 'SDXL 1.0', aliases: ['sdxl', 'sdxl10', 'sdxl 1.0', 'stable diffusion xl'] },
|
||||
{ value: 'SD 1.5', aliases: ['sd15', 'sd 1.5', 'sd1.5', 'stable diffusion 1.5'] },
|
||||
{ value: 'Flux.1 D', aliases: ['flux', 'flux1', 'flux.1', 'flux dev', 'flux.1 d', 'flux1d'] },
|
||||
{ value: 'Flux.1 S', aliases: ['flux schnell', 'flux.1 s', 'flux1s'] },
|
||||
{ value: 'Qwen Image', aliases: ['qwen image', 'qwenimage', 'qwen-image'] },
|
||||
{ value: 'Hunyuan 1', aliases: ['hunyuan', 'hunyuan1'] },
|
||||
{ value: 'WAN Video', aliases: ['wan', 'wan video', 'wanvideo'] },
|
||||
{ value: 'NoobAI', aliases: ['noobai', 'noob ai'] },
|
||||
{ value: 'HiDream', aliases: ['hidream', 'hi dream'] }
|
||||
];
|
||||
},
|
||||
|
||||
getWorkflowModelReferenceText() {
|
||||
const workflow = this.getCurrentWorkflow?.();
|
||||
if (!workflow) return '';
|
||||
|
||||
Reference in New Issue
Block a user